If IQueryable stored in local variable and used in subquery
Sample (DO 5.0.17)
namespace Sample
{
using System.Linq;
using System.Linq.Expressions;
using NUnit.Framework;
using Xtensive.IoC;
using Xtensive.Orm;
using Xtensive.Orm.Configuration;
internal class Program
{
private static void Main(string[] args)
{
var dc = new DomainConfiguration("sqlserver",
"Data Source=.; Initial Catalog=DO40-Tests; Integrated Security=True;");
dc.Types.Register(typeof(TestEntity));
dc.Types.Register(typeof(Preprocessor));
dc.UpgradeMode = DomainUpgradeMode.Recreate;
using (var d = Domain.Build(dc))
{
using (var s = d.OpenSession())
using (s.Activate())
using (var t = s.OpenTransaction())
{
new TestEntity(s) { String = "test" };
t.Complete();
}
using (var s = d.OpenSession())
using (s.Activate())
using (var t = s.OpenTransaction())
{
var simpleQuery = Query.All<TestEntity>().Count(e => e.Id == TestMethod());
// OK
Assert.AreEqual(1, simpleQuery);
var simpleJoin = Query.All<TestEntity>().Where(e => e.Id == TestMethod())
.Join(
Query.All<TestEntity>().Where(e => e.Id == TestMethod()),
o => o.Id,
i => i.Id,
(o, i) => o)
.Count();
// OK
Assert.AreEqual(1, simpleJoin);
var query = Query.All<TestEntity>().Where(e => e.Id == TestMethod());
var variableJoin = Query.All<TestEntity>().Where(e => e.Id == TestMethod())
.Join(
query,
o => o.Id,
i => i.Id,
(o, i) => o)
.Count();
// OK
Assert.AreEqual(1, variableJoin);
var anyCount = Query.All<TestEntity>()
.Count(e => e.Id == TestMethod() && Query.All<TestEntity>().Where(i => i.Id == TestMethod()).Any(z => z.Id == e.Id));
// OK
Assert.AreEqual(1, anyCount);
var linqCount = (from a in Query.All<TestEntity>().Where(e => e.Id == TestMethod())
from b in Query.All<TestEntity>().Where(e => e.Id == TestMethod())
where b.Id == a.Id
select a).Count();
// OK
Assert.AreEqual(1, linqCount);
var anyCountFail = Query.All<TestEntity>()
.Count(e => e.Id == TestMethod() && query.Any(z => z.Id == e.Id));
// FAIL
Assert.AreEqual(1, anyCountFail);
var linqCountFail = (from a in Query.All<TestEntity>().Where(e => e.Id == TestMethod())
from b in query
where b.Id == a.Id
select a).Count();
// FAIL
Assert.AreEqual(1, linqCountFail);
t.Complete();
}
}
}
private static int TestMethod()
{
return 2;
}
[HierarchyRoot]
public class TestEntity : Entity
{
/// <summary>Initializes a new instance of this class.</summary>
/// <param name="session">The session.</param>
public TestEntity(Session session) : base(session)
{
}
[Key]
[Field(Nullable = false)]
public int Id { get; private set; }
[Field]
public string String { get; set; }
}
/// <summary>
/// Translation preprocessor
/// </summary>
[Service(typeof(IQueryPreprocessor))]
public class Preprocessor : IQueryPreprocessor
{
/// <summary>Applies the preprocessor to the specified query.</summary>
/// <param name="query">The query to apply the preprocessor to.</param>
/// <returns>Application (preprocessing) result.</returns>
public Expression Apply(Expression query)
{
return new TestVisitor().Visit(query);
}
/// <summary>
/// Determines whether this query preprocessor is dependent on the <paramref name="other" /> one.
/// </summary>
/// <param name="other">The other query preprocessor.</param>
/// <returns>
/// <see langword="true" /> if this query preprocessor
/// is dependent on <paramref name="other" />;
/// otherwise, <see langword="false" />.
/// </returns>
public bool IsDependentOn(IQueryPreprocessor other)
{
return false;
}
}
public class TestVisitor : ExpressionVisitor
{
/// <summary>Visits the children of the <see cref="T:System.Linq.Expressions.MethodCallExpression" />.</summary>
/// <returns>The modified expression, if it or any subexpression was modified; otherwise, returns the original expression.</returns>
/// <param name="node">The expression to visit.</param>
protected override Expression VisitMethodCall(MethodCallExpression node)
{
return node.Method.Name == "TestMethod"
? Expression.Constant(1, typeof(int))
: base.VisitMethodCall(node);
}
}
}
}
asked
Aug 22 '18 at 05:46
Gushchin Anton
11●27●27●29