有一种名为Product的实体类型是由实体框架生成的。 我写了这个问题

public IQueryable<Product> GetProducts(int categoryID)
{
    return from p in db.Products
           where p.CategoryID== categoryID
           select new Product { Name = p.Name};
}

下面的代码抛出以下错误:

实体或复杂类型的Shop。产品不能构造在 LINQ到实体查询"

var products = productRepository.GetProducts(1).Tolist();

但是当我使用select p而不是select new Product {Name = p.Name};它工作正常。

如何执行自定义选择节?


当前回答

为了回应另一个被标记为重复的问题(见这里),我根据Soren的答案想出了一个快速而简单的解决方案:

data.Tasks.AddRange(
    data.Task.AsEnumerable().Select(t => new Task{
        creator_id   = t.ID,
        start_date   = t.Incident.DateOpened,
        end_date     = t.Incident.DateCLosed,
        product_code = t.Incident.ProductCode
        // so on...
    })
);
data.SaveChanges();

注意: 这个解决方案只适用于Task类上有一个导航属性(外键)(这里称为“Incident”)。 如果你没有,你可以使用“AsQueryable()”其他发布的解决方案之一。

其他回答

如果你正在使用实体框架,那么尝试从DbContext中删除属性,它使用你的复杂模型作为实体 当映射多个模型到名为实体的视图模型时,我也有同样的问题

public DbSet<Entity> Entities { get; set; }

从DbContext中删除条目修复了我的错误。

您不能(也不应该)将项目投射到映射实体上。但是,你可以投射到匿名类型或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();
}

只添加AsEnumerable():

public IQueryable<Product> GetProducts(int categoryID)
{
    return from p in db.Products.AsEnumerable()
           where p.CategoryID== categoryID
           select new Product { Name = p.Name};
}

你可以像下面这样添加AsEnumerable到你的集合:

public IQueryable<Product> GetProducts(int categoryID)
{
    return from p in db.Products.AsEnumerable()
           where p.CategoryID== categoryID
           select new Product { Name = p.Name};
}

如果你正在执行实体的Linq,你不能在查询的选择闭包中使用带有new的ClassType,只允许匿名类型(new没有类型)

看看我的项目的这个片段

//...
var dbQuery = context.Set<Letter>()
                .Include(letter => letter.LetterStatus)
                .Select(l => new {Title =l.Title,ID = l.ID, LastModificationDate = l.LastModificationDate, DateCreated = l.DateCreated,LetterStatus = new {ID = l.LetterStatusID.Value,NameInArabic = l.LetterStatus.NameInArabic,NameInEnglish = l.LetterStatus.NameInEnglish} })
                               ^^ without type__________________________________________________________________________________________________________^^ without type

如果你在选择闭包中添加了new关键字,即使在复杂的属性上,你也会得到这个错误

因此,从Linq上的new关键字删除类类型到实体查询,

因为它将转换为sql语句并在SqlServer上执行

什么时候我可以使用new with types on select closure?

如果你在处理LINQ to Object(内存收集),你可以使用它

//opecations in tempList , LINQ to Entities; so we can not use class types in select only anonymous types are allowed
var tempList = dbQuery.Skip(10).Take(10).ToList();// this is list of <anonymous type> so we have to convert it so list of <letter>

//opecations in list , LINQ to Object; so we can use class types in select
list = tempList.Select(l => new Letter{ Title = l.Title, ID = l.ID, LastModificationDate = l.LastModificationDate, DateCreated = l.DateCreated, LetterStatus = new LetterStatus{ ID = l.LetterStatus.ID, NameInArabic = l.LetterStatus.NameInArabic, NameInEnglish = l.LetterStatus.NameInEnglish } }).ToList();
                                ^^^^^^ with type 

在我对查询执行了ToList后,它变成了内存集合,所以我们可以在选择中使用新的classttypes