我是EF和linq的初学者。 我的模型包括产品/产品类型/参数/产品参数表。我在通过Include()方法使用紧急加载来加载数据时遇到一些困难。我需要从4个表中获取相关数据:fieldes产品-> fielde产品类型名称-> fielde参数名称-> fielde产品参数值
模型和DTO:
public class Product
{
public long ProductId { get; set; }
public string Name { get; set; }
public string Number { get; set; }
public double Amount { get; set; }
public double PrimeCostEUR { get; set; }
public long ProductTypeId { get; set; }
public ProductType ProductType { get; set; }
public ICollection<ProductParameter> ProductParameters { get; set; } =
new List<ProductParameter>();
}
public class ProductType
{
public long ProductTypeId { get; set; }
public string NameType { get; set; }
public ICollection<Product> Products { get; set; }
public ICollection<Parameter> Parameters { get; set; }
}
public class Parameter
{
public long ParameterId { get; set; }
public string Name { get; set; }
public long ProductTypeId { get; set; }
public ProductType ProductType { get; set; }
public ICollection<ProductParameter> ProductParameters { get; set; } =
new List<ProductParameter>();
}
public class ProductParameter
{
public long ProductParameterId { get; set; }
public long ProductId { get; set; }
public long ParameterId { get; set; }
public Parameter Parameter { get; set; }
public Product Product { get; set; }
public string Value { get; set; }
}
public class ProductDTO
{
public long ProductId { get; set; }
public string Number { get; set; }
public double Amount { get; set; }
public double PrimeCostEUR { get; set; }
public long ProductTypeId { get; set; }
public string NameType { get; set; }
public long ParameterId { get; set; }
public string Name { get; set; }
public long ProductParameterId { get; set; }
public string Value { get; set; }
}
这是我的方法
public async Task<IEnumerable<ProductDTO>> GetProducts()
{
var items = await _context.Products
.Include(t => t.ProductType)
.ThenInclude(p => p.Parameters)
.ThenInclude(pp => pp.ProductParameters)
.Include(t => t.ProductParameters)
.Select(p => new ProductDTO
{
ProductId = p.ProductId,
Number = p.Number,
Amount = p.Amount,
PrimeCostEUR = p.PrimeCostEUR,
NameType = p.ProductType.NameType,
ProductTypeId = p.ProductTypeId,
Name = p.Parameter.Name,
Value = p.ProductParameter.Value
})
.Where(p => p.ProductTypeId == 1)
.ToListAsync();
return items;
}
这是我遇到的错误:
错误CS1061'产品'不包含'参数'/'产品参数'的定义,并且找不到可以接受的扩展方法'参数'接受类型为'产品'的第一个参数(您是否缺少using指令或组装参考?
答案 0 :(得分:1)
Include
仅执行急切的加载,在执行Select
操作时不是必需的。从我的角度来看,如果您尝试从Product实体加载Parameter和ProductParameter,并且您提供的代码甚至都不应编译,并且该实体没有任何引用。
首先要看的是您的实体关系。查看您的对象模型,您似乎在Product和ProductType之间具有多对一的关系,然后在ProductParameter表的帮助下,在Product和Parameter之间具有多对多的关系。在ProductType上也有一个Parameters集合,我对此相当怀疑。处理关系时,我建议默认情况下使用单向引用,并且仅在需要时才启用双向引用。例如,一个产品需要引用一个产品类型,但是,产品类型真的需要引用该类型的所有产品吗? (如果需要,可以通过从Product进行查询,我们仍然可以做到这一点)更少的双向引用更易于使用。
要获取产品DTO,您需要解决DTO是代表产品(带有参数)还是单个产品和参数的组合。一个产品具有多个参数,因此,如果DTO代表单个产品,则该DTO将需要处理一组参数。如果DTO表示产品和参数的组合,那么具有3个相关参数的产品将导致创建3个DTO。
对于第二种情况,考虑到您当前拥有的DTO结构,您将需要查看类似于以下内容的Linq查询:
var items = await _context.Products
.SelectMany(p => p.ProductParameters)
.Select(pp => new ProductDTO
{
ProductId = pp.ProductId,
Number = pp.Product.Number,
Amount = pp.Product.Amount,
PrimeCostEUR = pp.Product.PrimeCostEUR,
NameType = pp.Product.ProductType.NameType,
ProductTypeId = pp.Product.ProductTypeId,
Name = pp.Parameter.Name,
Value = pp.Value
})
.Where(pp => pp.Product.ProductTypeId == 1)
.ToListAsync();
return items;
查询将针对ProductParameters运行,以访问产品和每个参数以及产品参数值。