首页 > 解决方案 > 如何在选择中加入多个表(Ef core)?

问题描述

我有一个数据库模型: 在此处输入图像描述

表“产品”和“属性”不相关。但是每个产品都可以有一个属性列表。

为了向客户端发送带有附加属性和值的产品列表,我实现了以下逻辑: API 控制器方法:

[HttpGet("get")]
[AllowAnonymous]
public async Task<IActionResult> Get()
{
  var productList = await _db.Product
    .Include(p => p.Category)
    .Include(p => p.ProductType)
    .Take(25)
    .ToListAsync();

  var productListJson = await HandleProductEntities(productList);

  return Ok(productListJson.ToString());
}

以及形成具有属性的产品 json-object 的方法:

private async Task<JArray> HandleProductEntities(IEnumerable<Product> productList)
{
  if (productList == null) throw new ArgumentNullException(nameof(productList));
  var productListJson = new JArray();
  foreach (var productEntity in productList)
  {
    var attributesList = await _db.ProductAttributeValues
      .Where(pav => pav.ProductId == productEntity.Id)
      .Select(pav => new
      {
        Id = pav.AttributeValue.Attribute.Id,
        Name = pav.AttributeValue.Attribute.Name,
        DisplayName = pav.AttributeValue.Attribute.DisplayName,
        Value = pav.AttributeValue.Value,
        ValueDescription = pav.AttributeValue.Description
      }).ToListAsync();

    var jsonSerializerSettings = new JsonSerializerSettings
    {
      ContractResolver = new CamelCasePropertyNamesContractResolver()
    };
    var productJson = JObject.Parse(JsonConvert.SerializeObject(productEntity, jsonSerializerSettings));

    var attrArrayJson = JArray.Parse(JsonConvert.SerializeObject(attributesList, jsonSerializerSettings));
    foreach (var token in attrArrayJson)
    {
      var paramName = (string) token["name"];
      if (paramName == null)
      {
        throw new NullReferenceException();
      }

      productJson.Add(paramName, token);
    }

    productListJson.Add(productJson);
  }

  return productListJson;
}

但是这个逻辑是超载的。可能有一种更简单的方法可以使用 EF 核心从数据库中获取具有属性的产品。有人能告诉我怎么做吗?

我试图这样做:

var resultTest = from productAttributeValue in _db.ProductAttributeValues
  join attributeValue in _db.AttributeValue on productAttributeValue.AttributeValueId equals attributeValue.Id
  join product in _db.Product on productAttributeValue.ProductId equals product.Id
  join attribute in _db.Attribute on attributeValue.AttributeId equals attribute.Id
  select new
  {
    Name = product.Name,
    Attribute = attribute.Name,
    AttributeValue = attributeValue,
  };

但是不可能对每个产品的属性进行分组。

标签: c#asp.net-coreasp.net-web-apientity-framework-core

解决方案


from product in _db.Product
join pav in _db.ProductAttributeValues on product.Id equals 
productAttributeValue.ProductId into productAttributeValueList
from productAttributeValue in productAttributeValueList.DefaultIfEmpty()
join attributeValue in _db.AttributeValue on productAttributeValue.AttributeValueId equals attributeValue.Id
join attribute in _db.Attribute on attributeValue.AttributeId equals attribute.Id
select new 
{
    Name = product.Name,
    Attribute = attribute.Name,
    AttributeValue = attributeValue
}

推荐阅读