如何在两个表之间的SQL/LINQ查询中找到重叠属性的计数?

如何在两个表之间的SQL/LINQ查询中找到重叠属性的计数?,linq,linq-to-sql,entity-framework-core,Linq,Linq To Sql,Entity Framework Core,假设我有两张桌子。这里我只展示了必要的内容,但是两个表ShoppingListA和ShoppingListB具有其他属性,并且FK指向不同的对象,但是它们都有一个“name”属性 public class ShoppingListA { public int Id { get; set; } public string Name { get; set; } } public class ShoppingListB { public int Id { get; set; } pu

假设我有两张桌子。这里我只展示了必要的内容,但是两个表
ShoppingListA
ShoppingListB
具有其他属性,并且FK指向不同的对象,但是它们都有一个“
name
”属性

public class ShoppingListA
{
  public int Id { get; set; }
  public string Name { get; set; }
}

public class ShoppingListB
{
  public int Id { get; set; }
  public string Name { get; set; }
}
我有以下的DTO

public class ShoppingListDto
{
   public int Id { get; set; }
   public string Name { get; set; }
   public int Count {get; set;}
}
此外,我有一种回购方法,该方法:

public async Task<List<ShoppingListDto>> GetShoppingLists()
{
       var shoppingListsA = await dbContext.ShoppingListA.Select(shoppingList => new ShoppingListDto
       {
           Id = shoppingList.Id,
           Name = shoppingList.Name,
        }).ToListAsync();

        var shoppingListsB = await dbContext.ShoppingListB.Select(shoppingList => new ShoppingListDto
       {
           Id = shoppingList.Id,
           Name = shoppingList.Name,
        }).ToListAsync()

      var allShoppingLists = shoppingListsA.Concat(shoppingListsB).ToList();
      return allShoppingLists;
}
假设shoppingListB是:

[
  { 
    id: 3795794697,
    name: "BBQ stuff"
  },
 { 
    id: q845846q868,
    name: "Dinner party"
  },
]
然后我的GetShoppingList方法将返回:

[
      { 
        id: 3795794697,
        name: "BBQ stuff",
        count: 1,
      },
     { 
        id: q845846q868,
        name: "Dinner party",
        count: 2,
      },
     { 
        id: 2342352235,
        name: "Weekend Groceries",
        count: 1,
      },
     { 
        id: 457457543,
        name: "Dinner party",
        count: 2,
      },
]

要收集重叠属性的计数,您只需要对连接的表进行分组

var查询=
从dbContext.ShoppingListA中的
在a上的dbContext.ShoppingListB中加入b。名称等于b。名称
将a组按a名称分为g组
选择ShoppingListDto
{
Id=//哪个Id?
名称=g.键,
Count=g.Count()
};

< /代码> 每当你有一个相似的项目序列,并且你想根据一些共同的值组成这些项目的组时,考虑使用一个超负荷的

在您的案例中:您希望创建购物列表组,其中一个组中的每个购物列表都具有相同的属性名称值

var shoppingListGroups = shoppinlists.GroupBy(shoppingList => shoppingList.Name,

// parameter resultSelector: for every Name, and all ShopplingLists with this name
// make one new:
(name, shoppingListsWithThisName) => new
{
    Name = name,
    ShoppingListsI = shoppingListsWithThisName.Select(shoppingList => new
    {
        shoppingList.Id,
        Name = shoppingList.Name,
        Count = shoppingListsWithThisName.Count(),
    })
    .ToList(),
});
换句话说:从您的ShoppingList序列中,创建ShoppingList组,其中每个组中的每个ShoppingList都具有相同的属性ShoppingList.Name值。从每个组名以及该组中的所有ShoppingList(均具有相同的名称)中,创建一个包含通用名称的对象,以及一个包含Id、名称和组中元素数量的对象列表(=具有此名称的所有ShoppingList)

我觉得这很没用,你已经知道了这个名字,为什么你要对组中的所有元素重复这个名字,为什么你要对组中的每个元素重复相同的计数。以下是更有效的方法:

"Grocery Shopping" has 3 elements with Ids {10, 23, 14}
"Dinner Party" has 2 elements with Ids {11, 12}
"BBQ stuff" has 1 element with Id {18}
如果需要,查询将更容易:

var shoppingListGroups = shoppinlists.GroupBy(shoppingList => shoppingList.Name,

(name, shoppingListsWithThisName) => new
{
    Name = name,
    Ids = shoppingListsWithThisName.Select(shoppingList => shoppingList.Id).ToList(),
}
换句话说:将ShoppingList.Name属性值相同的ShoppingList分组。对于每个组,创建一个对象,其中包含一个名称和ID列表。名称是组中所有购物清单的通用名称;该列表包含组中所有ShoppingList的ID。每个列表都有一个属性
Count
,因此您还可以知道每个组中的元素总数


结果会更有效,感觉更自然。

简单,但没有Id。
var shoppingListGroups = shoppinlists.GroupBy(shoppingList => shoppingList.Name,

(name, shoppingListsWithThisName) => new
{
    Name = name,
    Ids = shoppingListsWithThisName.Select(shoppingList => shoppingList.Id).ToList(),
}