实体不能在LINQ to Entities查询中构造
有一个实体类型称为产品,由实体框架生成。 我写了这个查询
public IQueryable<Product> GetProducts(int categoryID)
{
return from p in db.Products
where p.CategoryID== categoryID
select new Product { Name = p.Name};
}
下面的代码会引发以下错误:
“实体或复杂类型Shop.Product不能在LINQ to Entities查询中构建”
var products = productRepository.GetProducts(1).Tolist();
但是,当我使用select p
而不是select new Product { Name = p.Name};
它工作正常。
我如何预制自定义选择部分?
你不能(也不应该能够)投影到映射实体上。 但是,您可以投影到匿名类型或DTO上:
public class ProductDTO
{
public string Name { get; set; }
// Other field you may need from the Product entity
}
你的方法将返回一个DTO列表。
public List<ProductDTO> GetProducts(int categoryID)
{
return (from p in db.Products
where p.CategoryID == categoryID
select new ProductDTO { Name = p.Name }).ToList();
}
您可以投影到匿名类型,然后从它到模型类型
public IEnumerable<Product> GetProducts(int categoryID)
{
return (from p in Context.Set<Product>()
where p.CategoryID == categoryID
select new { Name = p.Name }).ToList()
.Select(x => new Product { Name = x.Name });
}
编辑 :我会更具体一些,因为这个问题引起了很多关注。
你不能直接投影到模型类型(EF限制),所以没有办法解决这个问题。 唯一的方法是投射到匿名类型(第一次迭代),然后到模型类型(第二次迭代)。
另请注意,当您以这种方式部分加载实体时,它们无法更新,因此它们应保持分离状态。
我从来没有完全理解为什么这是不可能的,并且这个线程的答案没有给出强烈的理由来反对它(主要是关于部分加载的数据)。 在部分加载的状态实体不能被更新是正确的,但是这个实体将被分离,所以意外的尝试来保存它们是不可能的。
考虑我上面使用的方法:结果我们仍然有一个部分加载的模型实体。 此实体已分离。
考虑这个(希望存在的)可能的代码:
return (from p in Context.Set<Product>()
where p.CategoryID == categoryID
select new Product { Name = p.Name }).AsNoTracking().ToList();
这也可能导致分离实体列表,所以我们不需要做两次迭代。 编译器会很聪明地看到AsNoTracking()已被使用,这会导致分离的实体,所以它可以让我们做到这一点。 但是,如果省略了AsNoTracking(),它可能会抛出与现在抛出异常相同的异常,以警告我们需要对我们想要的结果足够具体。
我找到了另一种方法,你必须建立一个派生自你的Product类并使用它的类。 例如:
public class PseudoProduct : Product { }
public IQueryable<Product> GetProducts(int categoryID)
{
return from p in db.Products
where p.CategoryID== categoryID
select new PseudoProduct() { Name = p.Name};
}
不知道这是否“允许”,但它的作品。
链接地址: http://www.djcxy.com/p/21119.html上一篇: The entity cannot be constructed in a LINQ to Entities query