dataobjects-net
dataobjects-net copied to clipboard
Mistreating ENUMs whenever they are backed by something else than int
I am running into repeated issues whenever I work with enum
fields which are backed by anything else but int
.
This simple query:
// fetch all current CNP settings for the given cards
var projection =
from cardSec in qe.All<Model.CardSecurity>()
join cnp in qe.All<Model.CardCnpSetting>() on cardSec equals cnp.AsCurrent
where QueryableExtensions.In<int>(cardSec.CardID, parentKeys)
&& cnp.State == HistoryTrackedItemState.Current
select new { cardSec.CardID, cnp };
causes an exception:
Xtensive.Orm.QueryTranslationException: 'Unable to translate 'Query.All().Join(
Query.All(),
cardSec => cardSec,
cnp => cnp.AsCurrent,
(cardSec, cnp) => new @<cardSec, cnp>(
cardSec,
cnp
)
).Where(<>h__TransparentIdentifier0 => (<>h__TransparentIdentifier0.cardSec.CardID.In(@.parentKeys) && (((Int32)<>h__TransparentIdentifier0.cnp.State) == 5))).Select(<>h__TransparentIdentifier0 => new @<CardID, cnp>(
<>h__TransparentIdentifier0.cardSec.CardID,
<>h__TransparentIdentifier0.cnp
))' expression. See inner exception for details.'
The inner exception is an "Ambiguous match found." error. And this is the stack trace:
at System.RuntimeType.GetPropertyImpl(String name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers)
at System.Type.GetProperty(String name, BindingFlags bindingAttr)
at Xtensive.Orm.Linq.Translator.VisitMemberAccess(MemberExpression ma)
at Xtensive.Linq.ExpressionVisitor`1.Visit(Expression e)
at Xtensive.Linq.ExpressionVisitor.VisitUnary(UnaryExpression u)
at Xtensive.Orm.Linq.Translator.VisitUnary(UnaryExpression u)
at Xtensive.Linq.ExpressionVisitor`1.Visit(Expression e)
at Xtensive.Orm.Linq.Translator.VisitBinary(BinaryExpression binaryExpression)
at Xtensive.Linq.ExpressionVisitor`1.Visit(Expression e)
at Xtensive.Orm.Linq.Translator.VisitBinary(BinaryExpression binaryExpression)
at Xtensive.Linq.ExpressionVisitor`1.Visit(Expression e)
at Xtensive.Orm.Linq.Translator.VisitLambda(LambdaExpression le)
at Xtensive.Orm.Linq.Translator.VisitWhere(Expression expression, LambdaExpression le)
at Xtensive.Orm.Linq.Translator.VisitQueryableMethod(MethodCallExpression mc, QueryableMethodKind methodKind)
at Xtensive.Linq.QueryableVisitor.VisitMethodCall(MethodCallExpression mc)
at Xtensive.Orm.Linq.Translator.VisitMethodCall(MethodCallExpression mc)
at Xtensive.Linq.ExpressionVisitor`1.Visit(Expression e)
at Xtensive.Orm.Linq.Translator.VisitSequence(Expression sequenceExpression, Expression expressionPart)
at Xtensive.Orm.Linq.Translator.VisitSelect(Expression expression, LambdaExpression le)
at Xtensive.Orm.Linq.Translator.VisitQueryableMethod(MethodCallExpression mc, QueryableMethodKind methodKind)
at Xtensive.Linq.QueryableVisitor.VisitMethodCall(MethodCallExpression mc)
at Xtensive.Orm.Linq.Translator.VisitMethodCall(MethodCallExpression mc)
at Xtensive.Linq.ExpressionVisitor`1.Visit(Expression e)
at Xtensive.Orm.Linq.Translator.Translate()
at Xtensive.Orm.Linq.QueryProvider.Translate(Expression expression, CompilerConfiguration compilerConfiguration)
I can try updating to the latest master, in a few days, to confirm this as a pending bug. However, I do believe this has a similar root cause as the mistreatment of non-int fields in general. I have seen DO generate casts in SQL queries, completely unnecessary, such as this: …AND ( CAST([a].[id_arch] AS integer) = 0));
, where id_arch
is a smallint
column (short
in C#).
It's a pain and I hope @alex-kulakov and the team will pay attention to this. I already know how to write unit tests in DO codebase, so I will try contributing at least tests to identify these issues.