Skip to content

Underlying enum values are not mapped to the database enumeration for types registered into the npgsql type mapping #593

Description

@dpsenner

Still investigating into ways to interact with composite types in the postgresql database, we defined a composite that uses a database defined enum. While following this outline we added ModelBuilder.ForNpgsqlHasEnum invocations and further added a plugin that translates composite type members such that the composite type member is mapped in the query. It does so by implementing a custom Expression that basically does this:

// a class that extends Microsoft.EntityFrameworkCore.Query.ExpressionTranslators.IMemberTranslatorpublicExpressionTranslate(MemberExpressionmemberExpression){if(memberExpression.Member==ValueMember){returnnewGetCompositeTypeMemberExpression(NpgsqlNameTranslator,memberExpression.Expression,memberExpression.Member);}if(memberExpression.Member==UnitMember){returnnewGetCompositeTypeMemberExpression(NpgsqlNameTranslator,memberExpression.Expression,memberExpression.Member);}returnnull;}// a class that extends System.Linq.Expressions.ExpressionprotectedoverrideExpressionAccept(ExpressionVisitorvisitor){varleftBracket=newCustomUnaryExpression(Instance,"(",Instance.Type,false);varrightBracket=newCustomUnaryExpression(leftBracket,")",Instance.Type,true);varmemberExpression=newCustomUnaryExpression(rightBracket,$".{MemberName}",Type,true);returnmemberExpression;}

This works exceptionally well and generates good queries that look alike:

2018-08-14 16:01:27.065 +02:00 [Error] [7856816] [14] [] [] [:] [Microsoft.EntityFrameworkCore.Database.Command] Failed executing DbCommand ("11"ms) [Parameters=[""], CommandType='Text', CommandTimeout='600']"
""SELECT t.id, (t.weight).value, (t.weight).unit
FROM sandbox.weighing AS t"

Unfortunately when adding a simple where clause in the query as follows:

storage.WeighingRecords.Where(t =>t.Weight.Unit==WeightUnit.Tonne)

the following happens:

2018-08-14 16:01:27.065 +02:00 [Error] [7856816] [14] [] [] [:] [Microsoft.EntityFrameworkCore.Database.Command] Failed executing DbCommand ("11"ms) [Parameters=[""], CommandType='Text', CommandTimeout='600']"
""SELECT t.id, (t.weight).value, (t.weight).unit
FROM sandbox.weighing AS t
WHERE (t.weight).unit = 6"
Npgsql.PostgresException (0x80004005): 42883: operator does not exist: units.weight_unit = integer

When I refactor the where argument out of the query such that it becomes a query parameter the query works as expected:

varweightUnit=WeightUnit.Tonne;varactualWeighingRecords=storage.WeighingRecords.Where(t =>t.Weight.Unit==weightUnit)
2018-08-14 16:13:28.360 +02:00 [Information] [8553120] [17] [] [] [:] [Microsoft.EntityFrameworkCore.Database.Command] Executed DbCommand ("10"ms) [Parameters=["@__weightUnit_0='Tonne' (DbType = Object)"], CommandType='Text', CommandTimeout='600']"
""SELECT t.id, (t.weight).value, (t.weight).unit
FROM sandbox.weighing AS t
WHERE (t.weight).unit = @__weightUnit_0"

Is there a way to make this query work without that extra parameter?

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions