实体导航属性IQueryable无法转换为商店表达式

时间:2014-12-18 14:38:52

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

我首先使用Entity Framework设计器,我需要从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
        });
    }

但我真的无法弄清楚如何使用它。

2 个答案:

答案 0 :(得分: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()
});

答案 1 :(得分:0)

问题在于LINQ to Entities正在尝试将您的ToModel()方法转换为SQL查询(因为那是LINQ to Entities应该做的事情),并且它无法找到一种方法,因此你会看到错误。

为了让你调用ToModel(),你需要从数据库中获取信息,然后将任何LINQ查询作为LINQ to Objects查询,这将超过能力做你想要的。您可以在致电ToList()之前致电ToModel()来执行此操作。