Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# linq中的Group by和left join_C#_Linq_Linq To Sql - Fatal编程技术网

C# linq中的Group by和left join

C# linq中的Group by和left join,c#,linq,linq-to-sql,C#,Linq,Linq To Sql,有两个表,一个是customers有字段customerID,GroupID,另一个是CustomerGroup有字段GroupID,GroupName,我想得到每个组中customerID的数量,下面是LINQ语句: var groups = from customerGroups in db.CustomerGroup join customers in db.Customers on customerGroups.GroupID equa

有两个表,一个是customers有字段
customerID
GroupID
,另一个是
CustomerGroup
有字段
GroupID
GroupName
,我想得到每个组中
customerID
的数量,下面是LINQ语句:

var groups = from customerGroups in db.CustomerGroup 
                         join customers in db.Customers on customerGroups.GroupID equals customers.GroupID into gc
                         where customerGroups.MerchantID == merchantID
                         from subCustomerGroups in gc.DefaultIfEmpty()
                         group customerGroups by customerGroups.GroupName into grpCustomerGroups
                         select new { GroupName = grpCustomerGroups.Key, Quantity = customers.Count()};
问题是
Quantity=customers.Count()
无效,如何更正该语句? 预期的sql语句是

exec sp_executesql N'SELECT 
    1 AS [C1], 
    [GroupBy1].[K1] AS [GroupName], 
    [GroupBy1].[A1] AS [C2]
    FROM ( SELECT 
        [Extent1].[GroupName] AS [K1], 
        COUNT(CustomerID) AS [A1]
        FROM  [dbo].[CustomerGroup] AS [Extent1]
        LEFT OUTER JOIN [dbo].[Customer] AS [Extent2] ON [Extent1].[GroupID] = [Extent2].[GroupID]
        WHERE [Extent1].[MerchantID] = @p__linq__0
        GROUP BY [Extent1].[GroupName]
    )  AS [GroupBy1]',N'@p__linq__0 bigint',@p__linq__0=9

通常,如果你发现自己做了一个左外连接,后面跟着一个分组,那是因为你想要“带有他们的子项目的项目”,比如“带学生的学校”,“有订单的客户”,“CustomerGroups和他们的客户”等等。如果你想要这个,考虑使用而不是“加入+默认的+GROPBY”< /P>。 我更熟悉方法语法,所以我将使用该语法

int merchantId = ...
var result = dbContext.CustomerGroups

    // keep only the CustomerGroups from merchantId
    .Where(customerGroup => customerGroup.MerchantId == merchantId)

    .GroupJoin(dbContext.Customers,            // GroupJoin with Customers
    customerGroup => customerGroup.GroupId,    // from every CustomerGroup take the GroupId
    customer => customer.GroupId,              // from every Customer take the GroupId

    // ResultSelector:
    (customerGroup, customersInThisGroup) => new  // from every CustomerGroup with all its
    {                                             // matching customers make one new object
        GroupName = customerGroup.Key,
        Quantity = customersInThisGroup.CustomerId,  // ???
    });
简言之:

以CustomerGroup的序列为例。仅保留那些属性MerchantId的值等于MerchantId的CustomerGroup。通过比较CustomerGroup.GroupId与每个Customer.GroupId,从剩余的每个CustomerGroup中获取其所有客户

结果是一系列CustomerGroup,每个都有自己的客户。从该结果(参数ResultSelector)获取来自客户的GroupName和来自该组中客户的数量

你的声明是:

Quantity = customers.CustomerID,
这是行不通的。我肯定这不是你想要的。唉,你忘了写你想要的东西。我认为是这样的:

Quantity = customers.Count().
但如果您想要此CustomerGroup中所有客户的CustomerId:

// ResultSelector:
(customerGroup, customersInThisGroup) => new
{                                           
    GroupName = customerGroup.Key,
    CustomerIds = customersInThisGroup.Select(customer => customer.CustomerId)
                                      .ToList(),
);
如果需要,您可以使用ResultSelector获取“CustomerGroup with the Customers”。最有效的方法是仅选择实际计划使用的属性:

// ResultSelector:
(customerGroup, customersInThisGroup) => new
{      
    // select only the CustomerGroup properties that you plan to use:
    Id = CustomerGroup.GroupId,
    Name = CustomerGroup.Name,
    ... // other properties that you plan to use

    Customers = customersInThisGroup.Select(customer => new
    {
         // again, select only the Customer properties that you plan to use
         Id = customer.Id,
         Name = customer.Name,
         ...

         // not needed, you know the value:
         // GroupId = customer.GroupId
    });

不选择客户的外键的原因是效率。如果CustomerGroup[14]有1000个客户,则此组中的每个客户的GroupId值都将等于[14]。发送此值[14]1001次将是一种浪费。

根据您的回答,我做了一个小改动,它对我有效!(customerGroup,customersInThisGroup)=>新建//从每个customerGroup及其所有{//匹配的客户创建一个新对象GroupID=customerGroup.GroupID,GroupName=customerGroup.GroupName,Quantity=customersInThisGroup.Count(),});