【问题标题】:How to Select new model list after GroupBy mothod in Linq?如何在 Linq 中的 GroupBy 方法之后选择新模型列表?
【发布时间】:2015-03-10 12:00:33
【问题描述】:

我想选择分组的行到一个新的模型列表。这是我的代码:

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();

【问题讨论】:

  • 尝试 a.First().CompanyContactInfo.Email ... 为它的一个组...
  • 其他属性相同...
  • 在解决方案中分组后使用 .Select(a => a.FirstOrDefault()).Select...。感谢您的提示

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


【解决方案1】:

您可以使用.Select(g =&gt; g.First()) 而不是.SelectMany(a =&gt; a)。这将为您提供每个组的第一项。

(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();

请注意,这可能不受支持,如果是这种情况,请在 .Select(g =&gt; g.First()) 之前添加 AsEnumerable 调用

【讨论】:

  • 很好,工作正常。但我必须使用 FirstorDefault 而不是 First()。请编辑你有用的帖子。谢谢 Selman
【解决方案2】:

您应该明白,在您的 LinQ 表达式中执行 GroupBy() 之后,您将使用 group,因此在您的示例中,最好这样写:

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();

【讨论】:

  • 很好,可以正常工作。但我必须在所有列中使用 FirstOrDefault() 方法。在 groupby 更好之后使用 Select(g => g.First())。
【解决方案3】:

您可以尝试这样的事情,而不是混合查询表达式和方法...(根据需要在 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();

【讨论】:

  • 如果我在 'Where' 和 'select new' 中为 resulstSet 的每个字段添加 FirstOrDefault() 方法,则此代码有效。因此查询工作正常,但速度较低
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多