Gho*_*ngi 373 c# entity-framework
存在由实体框架生成的称为产品的实体类型.我写了这个查询
public IQueryable<Product> GetProducts(int categoryID)
{
return from p in db.Products
where p.CategoryID== categoryID
select new Product { Name = p.Name};
}
Run Code Online (Sandbox Code Playgroud)
下面的代码引发以下错误:
"无法在LINQ to Entities查询中构造实体或复杂类型Shop.Product"
var products = productRepository.GetProducts(1).Tolist();
Run Code Online (Sandbox Code Playgroud)
但是,当我使用select p而不是select new Product { Name = p.Name};它正常工作.
如何预先形成自定义选择部分?
Yak*_*ych 376
您不能(也不应该)投影到映射的实体.但是,您可以投影到匿名类型或DTO:
public class ProductDTO
{
public string Name { get; set; }
// Other field you may need from the Product entity
}
Run Code Online (Sandbox Code Playgroud)
并且您的方法将返回DTO列表.
public List<ProductDTO> GetProducts(int categoryID)
{
return (from p in db.Products
where p.CategoryID == categoryID
select new ProductDTO { Name = p.Name }).ToList();
}
Run Code Online (Sandbox Code Playgroud)
Gor*_*ran 263
您可以投影到匿名类型,然后从它投射到模型类型
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 });
}
Run Code Online (Sandbox Code Playgroud)
编辑:由于这个问题得到了很多关注,我将会更具体一点.
你不能直接投射到模型类型(EF限制),所以没有办法解决这个问题.唯一的方法是投射到匿名类型(第一次迭代),然后投射到模型类型(第二次迭代).
另请注意,当您以这种方式部分加载实体时,它们无法更新,因此它们应保持分离状态.
我从来没有完全理解为什么这是不可能的,并且这个线程的答案没有给出强有力的理由(主要是关于部分加载的数据).在部分加载的状态实体无法更新是正确的,但是,此实体将被分离,因此不可能意外地尝试保存它们.
考虑我上面使用的方法:作为结果,我们仍然有一个部分加载的模型实体.该实体是分离的.
考虑这个(希望存在的)可能的代码:
return (from p in Context.Set<Product>()
where p.CategoryID == categoryID
select new Product { Name = p.Name }).AsNoTracking().ToList();
Run Code Online (Sandbox Code Playgroud)
这也可能导致分离实体列表,因此我们不需要进行两次迭代.编译器会很聪明地看到AsNoTracking()已被使用,这将导致分离的实体,因此它可以允许我们这样做.但是,如果省略了AsNoTracking(),它可能会抛出与现在抛出相同的异常,以警告我们需要对我们想要的结果做出足够的具体说明.
Tom*_*icz 78
我找到了另一种方法,你必须构建一个派生自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};
}
Run Code Online (Sandbox Code Playgroud)
不确定这是否"允许",但它确实有效.
Boj*_*kas 37
这是一种在不声明aditional类的情况下执行此操作的方法:
public List<Product> GetProducts(int categoryID)
{
var query = from p in db.Products
where p.CategoryID == categoryID
select new { Name = p.Name };
var products = query.ToList().Select(r => new Product
{
Name = r.Name;
}).ToList();
return products;
}
Run Code Online (Sandbox Code Playgroud)
但是,仅当您要在单个实体中组合多个实体时才使用此选项.上述功能(简单的产品到产品映射)是这样完成的:
public List<Product> GetProducts(int categoryID)
{
var query = from p in db.Products
where p.CategoryID == categoryID
select p;
var products = query.ToList();
return products;
}
Run Code Online (Sandbox Code Playgroud)
Sor*_*ren 22
另一种简单方法:)
public IQueryable<Product> GetProducts(int categoryID)
{
var productList = db.Products
.Where(p => p.CategoryID == categoryID)
.Select(item =>
new Product
{
Name = item.Name
})
.ToList()
.AsQueryable(); // actually it's not useful after "ToList()" :D
return productList;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
222992 次 |
| 最近记录: |