Hello, i am getting NotSupportedException when trying to compare result of ternary conditional operator with already materialized entity.
Here is how to reproduce it:
[HierarchyRoot]
public class First : Entity
{
public First(Guid id) : base(id)
{
}
[Field]
[Key]
public Guid Id { get; private set; }
[Field]
public Second Second { get; set; }
}
[HierarchyRoot]
public class Second : Entity
{
public Second(Guid id) : base(id)
{
}
[Field]
[Key]
public Guid Id { get; private set; }
}
class Program
{
static void Main(string[] args)
{
var dc = new DomainConfiguration("sqlserver", "Data Source=.; Initial Catalog=DO41-Tests;Connection Timeout=300;Integrated Security = true;Max pool size=2");
dc.Types.Register(typeof(Program).Assembly);
dc.UpgradeMode = DomainUpgradeMode.Recreate;
using (var domain = Domain.Build(dc))
using (var session = domain.OpenSession(SessionType.Default))
using (session.Activate())
using (var tr = session.OpenTransaction())
{
var second1 = new Second(Guid.NewGuid());
var second2 = new Second(Guid.NewGuid());
session.Query.All<First>().Select(z => new
{
Id = z.Id,
Sum = z.Second != null ? z.Second : second1,
})
.Where(z => z.Sum == second2)
.ToArray();
}
}
}
and exception
Unhandled Exception: Xtensive.Orm.QueryTranslationException: Unable to translate 'Query.All().Select(z => new @<id, sum="">(
z.Id,
(z.Second != null)
? z.Second
: @.second1
)).Where(z => (z.Sum == @.second2))' expression. See inner exception for details. ---> System.NotSupportedException: Both left and right part of binary expression '(IIF((Convert(Field Id, [2 ... 1]) != null), Entity Second, value(Sample.Program+<>cDisplayClas
s0_0).second1) == value(Sample.Program+<>cDisplayClass0_0).second2)' are NULL or not EntityExpression(EntityFieldExpression).
at Xtensive.Orm.Linq.Translator.VisitBinaryRecursive(BinaryExpression binaryExpression, BinaryExpression originalBinaryExpression)
at Xtensive.Orm.Linq.Translator.VisitBinary(BinaryExpression binaryExpression)
at Xtensive.Linq.ExpressionVisitor1.Visit(Expression e)
at Xtensive.Orm.Linq.Translator.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.Visit(Expression e)
at Xtensive.Orm.Linq.Translator.TranslateTResult
at Xtensive.Orm.Linq.QueryProvider.TranslateTResult
--- End of inner exception stack trace ---
at Xtensive.Orm.Linq.QueryProvider.TranslateTResult
at Xtensive.Orm.Linq.QueryProvider.TranslateTResult
at Xtensive.Orm.Linq.QueryProvider.ExecuteTResult
at Xtensive.Orm.Linq.Queryable1.GetEnumerator()
at System.Linq.Buffer
1..ctor(IEnumerable1 source)
at System.Linq.Enumerable.ToArray[TSource](IEnumerable
1 source)
at Sample.Program.Main(String[] args) in F:\Projects\CleanDO\Sample\Program.cs:line 69
UPD: Query in inital post is wrong. It should be like
session.Query.All<First>().Select(z => new
{
Id = z.Id,
Sum = z.Second != null
? z.Second
: session.Query.All<Second>().Single(x => x.Id == second1.Id),
})
.Where(z => z.Sum == second2)
.ToArray();
and exception is slightly different
Unhandled Exception: Xtensive.Orm.QueryTranslationException: Unable to translate 'Query.All().Select(z => new @<id, sum="">(
z.Id,
(z.Second != null)
? z.Second
: @.CS$<>8locals1.session.Query.All().Single(x => (x.Id == @.second1.Id))
)).Where(z => (z.Sum == @.second2))' expression. See inner exception for details. ---> System.InvalidCastException: Unable to cast object of type 'Xtensive.Orm.Linq.Expressions.MarkerExpression' to type 'Xtensive.Orm.Linq.Expressions.IEntityExpression'.
at Xtensive.Orm.Linq.Translator.GetConditionalKeyField(Expression expression, Type keyFieldType, Int32 index)
at Xtensive.Orm.Linq.Translator.GetConditionalKeyField(Expression expression, Type keyFieldType, Int32 index)
at Xtensive.Orm.Linq.Translator.<>cDisplayClass3e.<getentityfields>b3d(Type type, Int32 index)
at System.Linq.Enumerable.<selectiterator>d52.MoveNext()
at System.Collections.Generic.List
1..ctor(IEnumerable1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable
1 source)
at Xtensive.Orm.Linq.Translator.GetEntityFields(Expression expression, IEnumerable1 keyFieldTypes)
at Xtensive.Orm.Linq.Translator.VisitBinaryRecursive(BinaryExpression binaryExpression, BinaryExpression originalBinaryExpression)
at Xtensive.Orm.Linq.Translator.VisitBinary(BinaryExpression binaryExpression)
at Xtensive.Linq.ExpressionVisitor
1.Visit(Expression e)
at Xtensive.Orm.Linq.Translator.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.ExpressionVisitor1.Visit(Expression e)
at Xtensive.Orm.Linq.Translator.Visit(Expression e)
at Xtensive.Orm.Linq.Translator.Translate[TResult]()
at Xtensive.Orm.Linq.QueryProvider.Translate[TResult](Expression expression, CompilerConfiguration compilerConfiguration)
--- End of inner exception stack trace ---
at Xtensive.Orm.Linq.QueryProvider.Translate[TResult](Expression expression, CompilerConfiguration compilerConfiguration)
at Xtensive.Orm.Linq.QueryProvider.Translate[TResult](Expression expression)
at Xtensive.Orm.Linq.QueryProvider.Execute[TResult](Expression expression)
at Xtensive.Orm.Linq.Queryable
1.GetEnumerator()
at System.Linq.Buffer1..ctor(IEnumerable
1 source)
at System.Linq.Enumerable.ToArrayTSource
at Sample.Program.Main(String[] args) in F:\Projects\CleanDO\Sample\Program.cs:line 72