【问题标题】:Entity Navigation Property IQueryable cannot be translated into a store expression实体导航属性 IQueryable 无法转换为商店表达式
【发布时间】:2014-12-18 14:38:52
【问题描述】:

我首先使用实体​​框架设计器,我需要从 db 对象开始创建自定义模型对象。 我不想使用 IEnumerable,因为它会查询太多字段。

目标是删除此函数中的内部选择:

using (var db = new dbEntities())
{
   var departments= db.departments
                      .Include(p => p.employee)
                      .Where(...)
                      .Select(p => new CustomDepartmentModel()
                      {
                         ID = p.ID,
                         Employees = p.employee
                                .Select(q => new CustomEmployeeModel()
                                {
                                    ID = q.ID,
                                    Name= q.Name
                                }).ToList()
                      });
   return departments.ToList();
}

通过使用此功能:

public static IQueryable<CustomEmployeeModel> ToModel(this IQueryable<employee> Employee)
    {
        return Employee.Select(u => new CustomEmployeeModel()
        {
            ID = u.ID,
            Name = u.Name
        });
    }

但我总是收到错误消息:“LINQ to Entities 无法识别方法 ToModel”。

我确实尝试以这些方式使用它,但没有运气:

Employees = p.employee.AsQueryable().ToModel().ToList() //1
Employees = db.Entry(p).Collection(f => f.employee).Query().ToModel().ToList() //2

我认为我需要使用这样的东西:

public static System.Linq.Expressions.Expression<Func<IQueryable<employee>, IQueryable<CustomEmployeeModel>>> ToModel()
    {
        return p => p.Select(u => new CustomEmployeeModel()
        {
            ID = u.ID,
            Name = u.Name
        });
    }

但是我真的不知道怎么用。

【问题讨论】:

    标签: c# linq entity-framework linq-to-entities linq-expressions


    【解决方案1】:

    我认为我需要使用这样的东西:[snip] 但我真的不知道如何使用它。

    这正是您所需要的,但您还需要LINQKit 才能使查询正常工作。有了它,您的代码将如下所示:

    var toModel = ToModel();
    
    var departments2 = db.departments
        .AsExpandable()
        .Include(p => p.employee)
        .Where(p => true)
        .Select(p => new CustomDepartmentModel()
    {
        ID = p.ID,
        Employees = toModel.Invoke(p.employee).ToList()
    });
    

    【讨论】:

    • 看起来不错,但在严肃的项目中使用 LINQKit 是否安全?我需要确保代码不会因实体包更新而中断。那么扩展方法呢?你认为可以通过这种方式调用它:p.employee.ToModel() 吗?
    • @Simone LINQKit 不是 EF 特定的,它适用于任何 IQueryable,因此它应该适用于任何版本的 EF。而且我看不到如何直接使用扩展方法使其工作; LINQKit 查找对其Invoke() 的调用并对其进行处理,但它不知道它应该处理您的ToModel()
    【解决方案2】:

    问题是 LINQ to Entities 正在尝试将您的 ToModel() 方法转换为 SQL 查询(因为这是 LINQ to Entities 应该做的),但它找不到方法来做到这一点,因此您看到的错误。

    为了让您调用ToModel(),您需要已经从数据库中获取信息,这将使任何 LINQ 查询成为 LINQ to Objects 查询,这将比您做的更好正在要求。您可以通过在调用ToModel() 之前调用ToList() 来完成此操作。

    【讨论】:

    • 我只是想在外部方法中移动内部选择,我仍然想将内部选择翻译成sql语句,我不想​​使用 ToList() 否则它会查询其他参数太
    • 除了 LINQ to Entities 不是以允许它的方式构建的。您要么需要保留内部选择,要么先调用ToList
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多