Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Entity framework 创建表达式树以生成实体框架的参数化查询_Entity Framework_Expression Trees - Fatal编程技术网

Entity framework 创建表达式树以生成实体框架的参数化查询

Entity framework 创建表达式树以生成实体框架的参数化查询,entity-framework,expression-trees,Entity Framework,Expression Trees,我试图创建一个泛型类,用于为实体框架(5)组合查询 我让它工作了,唯一的问题是,值作为查询的常量而不是参数被注入。这减少了EF缓存查询并在以后重用它的可能性 这就是我目前得到的 public class MinDateFilter<T> : IFilter<T> where T : class { private readonly Expression<Func<T, bool>> _predicate; public MinDa

我试图创建一个泛型类,用于为实体框架(5)组合查询

我让它工作了,唯一的问题是,值作为查询的常量而不是参数被注入。这减少了EF缓存查询并在以后重用它的可能性

这就是我目前得到的

public class MinDateFilter<T> : IFilter<T> where T : class
{
    private readonly Expression<Func<T, bool>> _predicate;

    public MinDateCandidateFilter(Expression<Func<T, DateTime>> propertySelector, DateTime from)
    {
        from = from.Date.AddDays(-1);
        from = new DateTime(from.Year, from.Month, from.Day, 23, 59, 59, 999);

        Expression value = Expression.Constant(from, typeof(DateTime));
        //ParameterExpression variable = Expression.Variable(typeof(DateTime), "value");

        MemberExpression memberExpression = (MemberExpression)propertySelector.Body;
        ParameterExpression parameter = Expression.Parameter(typeof(T), "item");
        Expression exp = Expression.MakeMemberAccess(parameter, memberExpression.Member);

        Expression operation = Expression.GreaterThan(exp, value);
        //Expression operation = Expression.GreaterThan(exp, variable);
        _predicate = Expression.Lambda<Func<T, bool>>(operation, parameter);
    }

    public IQueryable<T> Filter(IQueryable<T> items)
    {
        return items.Where(_predicate);
    }
}
而不是

SELECT 
[Extent1].[Id] AS [Id]
-- Other fields
FROM [dbo].[Candidates] AS [Extent1]
WHERE [Extent1].[CreationDate] > @p__linq__0
如果我取消注释这两个注释行并注释上面的两行,我会得到一个错误,说明参数“value”没有绑定


我希望我提供了所有有用的详细信息:)

当参数作为
常量表达式传递时,如下所示:

Expression.Constant(myString)
。。。它将在生成的查询上生成一个固定不变的符号:

SELECT 
[Extent1].[Id] AS [Id], 
[Extent1].[Bar] AS [Bar], 
FROM [dbo].[Foo] AS [Extent1]
WHERE [Extent1].[Bar] = "Some text"
如果像我使用expression Tree Visualizer那样使用某种工具分析表达式,如
(f=>f.Bar==myString))
,您会看到该参数实际上是一个
MemberExpression
。 因此,如果要在结果查询中使用参数,必须传递对象的属性或更方便的匿名类型:

Expression.Property(
    Expression.Constant(new { Value = myString }),
    "Value"
)
这样,您将传递刚创建的对象的属性,表达式树将获得一个
MemberExpression
,从而产生以下
CommandText

SELECT 
[Extent1].[Id] AS [Id], 
[Extent1].[Bar] AS [Bar], 
FROM [dbo].[Foo] AS [Extent1]
WHERE [Extent1].[Bar] = @p__linq__0

你能解释一下为什么当前的结果不能满足你的需要吗?因为EF和SQL都不能使用第一个查询来正确缓存它们的输出。当然,EF将缓存已编译的查询,但除非输入完全相同,否则该缓存项将不可用。SQL Server也会发生同样的情况,它将缓存特定于此值的查询计划。我也有同样的问题。似乎无法传递Expression.Constant(myValue)。使用时,您可能会发现在检查实际工作查询时,该值作为MemberExpression传递,而不是ConstantExpression,但我仍然无法获取外部变量并使用Expression.Property或类似的方法传递它。谢谢:)我将尽快尝试:)
SELECT 
[Extent1].[Id] AS [Id], 
[Extent1].[Bar] AS [Bar], 
FROM [dbo].[Foo] AS [Extent1]
WHERE [Extent1].[Bar] = "Some text"
Expression.Property(
    Expression.Constant(new { Value = myString }),
    "Value"
)
SELECT 
[Extent1].[Id] AS [Id], 
[Extent1].[Bar] AS [Bar], 
FROM [dbo].[Foo] AS [Extent1]
WHERE [Extent1].[Bar] = @p__linq__0