EF包括不工作.选择新对象时缺少数据
本文关键字:数据 对象 工作 包括不 选择 新对象 EF | 更新日期: 2023-09-27 18:14:54
我想我误解了EF include或延迟加载,或者我没有正确设置我的实体。
如果我有这个查询,它按预期工作。我得到一个带有相关productopoptions的产品列表
var prodQuery = db.Products
.Include("ProductOptions")
.AsNoTracking()
.Where(p =>
p.CategoryId == category.Id
&& p.Active && !p.Deleted
&& p.ProductOptions.Any(po => po.Active && !po.Deleted)
).ToList();
然而,当我试图选择他们到DTO的…产品不包含productopoptions。不知为什么它们没有被包含
var products = db.Products
.Include("ProductOptions")
.AsNoTracking()
.Where(p =>
p.CategoryId == category.Id
&& p.Active && !p.Deleted
&& p.ProductOptions.Any(po => po.Active && !po.Deleted))
.Select(p =>
new ProductDTO
{
Id = p.Id,
Name = p.Name,
Description = p.Description,
ProductOptionDTOs = p.ProductOptions
.Where(po => po.Active && !po.Deleted)
.Select(po =>
new ProductOptionDTO
{
Id = po.Id,
Name = po.Name,
Price = po.Price
}
).ToList()
}
).ToList();
这是我的实体…删除了不相关的属性
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<ProductOption> ProductOptions { get; set; }
}
public class ProductOption
{
public int Id { get; set; }
public string Name { get; set; }
public int ProductId { get; set; }
public Product Product { get; set; }
}
有人能帮助我理解我在第二个查询中缺少productopoptions吗?
我的错误大家,不再是一个问题。谢谢你的帮助
在调查了每个人的建议并检查了我的代码之后,我发现我在ProductDTO (ProductOptionDTOs属性的声明)中犯了一个错误,它无声地失败并导致ProductOptionDTOs为空而没有错误。
在我测试了EF生成的sql后,我对我的DTO产生了怀疑,并发现sql正确地返回了正确的数据,因此我认为将它映射回DTO一定有问题。
所以事实证明,首先向你们展示我的DTO是至关重要的尽管我拒绝了这个想法
固定:)
你有
public ICollection<ProductOption> ProductOptions { get; set; }
ProductOptions = p.ProductOptions
.Where(po => po.Active && !po.Deleted)
.Select(po =>
new ProductOptionDTO
{
Id = po.Id,
Name = po.Name,
Price = po.Price
}).ToList()
注意与
的区别new ProductOptionDTO
和类
中productopoptions成员的类型ICollection<ProductOption>
所以试着改变
public ICollection<ProductOption> ProductOptions { get; set; }
public ICollection<ProductOptionDTO> ProductOptions { get; set; }
并将'ProductOption'类的名称更改为'ProductOptionDTO':
public class ProductOption
public class ProductOptionDTO
你的'Product'类不应该像下面这样改变吗?
public class Product
public class ProductDTO
编辑:尝试这个查询表达式如果只作为一个测试…
var products = (from p in db.Products
where p.CategoryId == category.Id
&& p.Active && !p.Deleted
&& p.ProductOptions.Any(po => po.Active && !po.Deleted)
select new ProductDTO
{
Id = p.Id,
Name = p.Name,
Description = p.Description,
ProductOptionDTOs = (from po in p.ProductOptions
where po.Active
&& !po.Deleted
select new ProductOptionDTO
{
Id = po.Id,
Name = po.Name,
Price = po.Price
}).ToList()
}).ToList()
EDIT2:如果上面不起作用,那么尝试在指定连接属性的地方…
var products = (from p in db.Products
where p.CategoryId == category.Id
&& p.Active && !p.Deleted
&& p.ProductOptions.Any(po => po.Active && !po.Deleted)
select new ProductDTO
{
Id = p.Id,
Name = p.Name,
Description = p.Description,
ProductOptionDTOs = (from po in db.ProductOptions
where po.ProductId == p.ProductId
&& po.Active
&& !po.Deleted
select new ProductOptionDTO
{
Id = po.Id,
Name = po.Name,
Price = po.Price
}).ToList()
}).ToList()
问题是Include
在执行复杂查询时不起作用。解决这个问题的一种方法是使用所谓的projection
。它只是在查询(new {...}
)中使用的动态类型。
试试这样写:
var products = db.Products
.AsNoTracking()
.Where(p =>
p.CategoryId == category.Id
&& p.Active && !p.Deleted
&& p.ProductOptions.Any(po => po.Active && !po.Deleted))
.Select(p =>
new
{
product = p,
options = p.ProductOptions.Where(po => po.Active && !po.Deleted)
}
)
.AsEnumerable()
.Select(s =>
new ProductDTO
{
Id = s.product.Id,
Name = s.product.Name,
Description = s.product.Description,
ProductOptionDTOs = s.options
.Select(po =>
new ProductOptionDTO
{
Id = po.Id,
Name = po.Name,
Price = po.Price
}
)
}
);