如何在Linq中的GroupBy方法之后选择新的模型列表?

时间:2015-03-10 12:00:33

标签: c# linq entity-framework model group-by

我希望选择分组的行到新的模型列表。这是我的代码:

List<Model_Bulk> q = (from a in db.Advertises 
                      join c in db.Companies on a.AdvertiseCompanyID equals c.CompanyID
                      where a.AdvertiseActive == true 
                            && a.AdvertiseExpireDate.HasValue 
                            && a.AdvertiseExpireDate.Value > DateTime.Now 
                            && (a.AdvertiseObjectType == 1 
                                || a.AdvertiseObjectType == 2)
                      select c)
     .GroupBy(a => a.CompanyID).Select(a => new Model_Bulk
     {
         CompanyEmail = a.CompanyContactInfo.Email,
         CompanyID = a.CompanyID,
         CompanyName = a.CompanyName,
         Mobile = a.CompanyContactInfo.Cell,
         UserEmail = a.User1.Email,
         categories = a.ComapnyCategories
     }).ToList();

分组后,我不能使用Select,自然会出现这种语法错误:

  

System.Linq.IGrouping'不包含'CompanyContactInfo'的定义,也没有扩展方法'CompanyContactInfo'接受类型的第一个参数   可以找到System.Linq.IGrouping'(您是否缺少using指令或程序集引用?)

如果我尝试使用SelectMany()方法。但结果将重复并且groupby方法无法正常工作:

List<Model_Bulk> q = (from a in db.Advertises
                      join c in db.Companies on a.AdvertiseCompanyID equals c.CompanyID
                      where a.AdvertiseActive == true 
                            && a.AdvertiseExpireDate.HasValue 
                            && a.AdvertiseExpireDate.Value > DateTime.Now 
                            && (a.AdvertiseObjectType == 1 
                                || a.AdvertiseObjectType == 2)
                      select c)
     .GroupBy(a => a.CompanyID).SelectMany(a => a).Select(a => new Model_Bulk
     {
         CompanyEmail = a.CompanyContactInfo.Email,
         CompanyID = a.CompanyID,
         CompanyName = a.CompanyName,
         Mobile = a.CompanyContactInfo.Cell,
         UserEmail = a.User1.Email,
         categories = a.ComapnyCategories
     }).ToList();

3 个答案:

答案 0 :(得分:4)

您可以使用.SelectMany(a => a)代替.Select(g => g.First())。这将为您提供每个组的第一项。

(from a in db.Advertises
                          join c in db.Companies on a.AdvertiseCompanyID equals c.CompanyID
                          where a.AdvertiseActive == true && a.AdvertiseExpireDate.HasValue && a.AdvertiseExpireDate.Value > DateTime.Now && (a.AdvertiseObjectType == 1 || a.AdvertiseObjectType == 2)
                          select c)
             .GroupBy(a => a.CompanyID)
             .Select(g => g.First())
             .Select(a => new Model_Bulk
             {
                 CompanyEmail = a.CompanyContactInfo.Email,
                 CompanyID = a.CompanyID,
                 CompanyName = a.CompanyName,
                 Mobile = a.CompanyContactInfo.Cell,
                 UserEmail = a.User1.Email,
                 categories = a.ComapnyCategories
             }).ToList();

请注意,这可能不受支持,如果是这种情况,请在AsEnumerable

之前添加.Select(g => g.First())来电

答案 1 :(得分:1)

您应该明白,在 LinQ 表达式GroupBy()后,您使用的是群组,所以在您的示例中,这样编写会很好:

List<Model_Bulk> q = 
    (from a in db.Advertises join c in db.Companies on a.AdvertiseCompanyID equals c.CompanyID                          
    where a.AdvertiseActive == true 
    && a.AdvertiseExpireDate.HasValue 
    && a.AdvertiseExpireDate.Value > DateTime.Now 
    && (a.AdvertiseObjectType == 1 || a.AdvertiseObjectType == 2)
    select c)
                 .GroupBy(a => a.CompanyID)
                 .Select(a => new Model_Bulk
                 {
                     CompanyEmail = a.First().CompanyContactInfo.Email,
                     CompanyID = a.Key, //Note this line, it's can be happened becouse of GroupBy()
                     CompanyName = a.First().CompanyName,
                     Mobile = a.First().CompanyContactInfo.Cell,
                     UserEmail = a.First().User1.Email,
                     categories = a.First().ComapnyCategories
                 }).ToList();

答案 2 :(得分:0)

相反,你可以尝试这样的东西,而不是混合查询表达式和方法......(在必要时使用where / select中的FirstOrDefault())

(from a in db.Advertises
join c in db.Companies on a.AdvertiseCompanyID equals c.CompanyID
group a by new { a.CompanyId } into resultsSet
where resultsSet.AdvertiseActive == true && resultsSet.AdvertiseExpireDate.HasValue && resultsSet.AdvertiseExpireDate.Value > DateTime.Now && (resultsSet.AdvertiseObjectType == 1 || resultsSet.AdvertiseObjectType == 2)
select new Model_Bulk
{
    CompanyEmail = resultsSet.CompanyContactInfo.Email,
    CompanyID = resultsSet.CompanyID,
    CompanyName = resultsSet.CompanyName,
    Mobile = resultsSet.CompanyContactInfo.Cell,
    UserEmail = resultsSet.User1.Email,
    categories = resultsSet.ComapnyCategories
}).ToList();