实体不能在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

下一篇: missing Embed Interop Type property