Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.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
C# 函数中带有表达式的编译LinQ查询_C#_.net_Entity Framework_Lambda_Linq To Entities - Fatal编程技术网

C# 函数中带有表达式的编译LinQ查询

C# 函数中带有表达式的编译LinQ查询,c#,.net,entity-framework,lambda,linq-to-entities,C#,.net,Entity Framework,Lambda,Linq To Entities,我想创建一个使用可重用where谓词的编译查询。有一个例子可以说明这一点: ObjectContext.Employees.Where(EmployeePredicates.CustomerPredicate) EmployeePredicates是一个静态类,其属性CustomerPredicate如下所示: public static Expression<Func<Employee, bool>> CustomerPredicate { g

我想创建一个使用可重用where谓词的编译查询。有一个例子可以说明这一点:

ObjectContext.Employees.Where(EmployeePredicates.CustomerPredicate)
EmployeePredicates是一个静态类,其属性CustomerPredicate如下所示:

public static Expression<Func<Employee, bool>> CustomerPredicate
    {
        get
        {
            return t => t.CustomerId == 1;
        }
    }
ObjectContext.Employees.Where(EmployeePredicates.CustomerPredicate(id))
public static Expression<Func<Employee, int, bool>> CustomerPredicate()
{
     return (t, id) => t.CustomerId == id;
}
这是可行的,但现在是棘手的部分。我想编译这个查询。。。Visual studio没有给我任何编译错误,但当我运行此示例时,会在运行时引发以下异常:

Internal .NET Framework Data Provider error 1025
我们在同一页,这里是给我例外的完整代码:

var _compiledQuery = CompiledQuery.Compile<AdventureWorksEntities, int, IQueryable<Employee>>(
                    (ctx, id) =>
                            (ctx.Employee.Where(EmployeePredicates.CustomerPredicate(id))
                        ));
在处理联接表时,情况会变得更糟

 (ctx, id, name) => 
    (ctx.Employee
     .Join(ctx.Contact, e=> e.ContactId, c => c.Id), (emp, cont) => new Container<Employee, Customer> {Employee = emp, Contact = cont})
    .Where(EmployeePredicates.CustomerPredicate(id))
    .Where(EmployeePredicates.NamePredicate(name))
    .Select(t => new EmployeeDTO {Name = t.cont.Name, Customer = e.emp.Customer})
(ctx、id、名称)=>
(ctx.Employee)
.Join(ctx.Contact,e=>e.ContactId,c=>c.Id),(emp,cont=>newcontainer{Employee=emp,Contact=cont})
.Where(雇员预测客户预测(id))
.Where(EmployeePredicates.NamePredicate(名称))
.Select(t=>newemployeedto{Name=t.cont.Name,Customer=e.emp.Customer})

因为每个Where()都对类型为T的内容进行操作并返回类型为T的内容,所以上面代码中的Where谓词必须对类型容器进行操作。这使得重用谓词非常困难。重用是这种方法的最初目标…

问题在于实体框架试图检查由

 (ctx, id) => (ctx.Employee.Where(EmployeePredicates.CustomerPredicate(id))
它不能这样做,因为它不知道
employeepredicate.CustomerPredicate
做什么

至于最好的解决办法。。。我不确定。基本上,它必须在查询编译时知道完整查询是什么样子的,只需使用占位符作为参数

    (ctx, id, name) => 
(ctx.Employee.Select(emp => new {emp, id})
.Where(EmployeePredicates.CustomerPredicate(id))
.Select(emp => new {emp, name})
.Where(EmployeePredicates.NamePredicate(name))
我认为最好的解决方案将包括以下内容:

public static Expression<Func<Employee, bool>> CustomerPredicate
    {
        get
        {
            return t => t.CustomerId == 1;
        }
    }
ObjectContext.Employees.Where(EmployeePredicates.CustomerPredicate(id))
public static Expression<Func<Employee, int, bool>> CustomerPredicate()
{
     return (t, id) => t.CustomerId == id;
}
公共静态表达式CustomerPredicate()
{
return(t,id)=>t.CustomerId==id;
}
。。。因为这将抽象提高了一个层次;它提供了一个表达式树,该表达式树使用
id
作为
参数表达式
,这是构建适当的表达式树以调用
编译器
所需的。不幸的是,这有点难以思考:(