【问题标题】:Can I do GroupBy in the query to avoid property in poco class?我可以在查询中执行 GroupBy 以避免 poco 类中的属性吗?
【发布时间】:2012-05-11 23:46:35
【问题描述】:

我在 db 中有 4 个表:

- News (NewsID(PK), NewsCategoryID(FK), NewsType (FK), NewsFormatID(FK), Caption, Description)
 - NewsType (NewsTypeID (PK), Caption)
 - NewsCategory(NewsCategoryID (PK), Caption)
 - NewsFormat (NewsFormatID (PK), Caption)

我有 2 个 POCO 对象:

public class News
{
    public int NewsID { get; set; }
    public int NewsTypeID { get; set; }
    public int NewsFormatID { get; set; }
    public string Category{ get; set; }
    public string Caption { get; set; }
    public string Description { get; set; }
}

public class NewsCategory
{
    public string Caption { get; set; }
    public List<News> News{ get; set; }
}

我想查询返回列表。在查询中,我想按类别对新闻进行分组。我是这样做的:

public static List<NewsCategory> GetNews()
    {
        using (var tc = new NewsDataContext())
        {
            var dc = tc.DataContext;
            var newsQuery= (from news in dc.News
                          join newsCategory in dc.NewsCategories on news.NewsCategoryID equals newsCategory.NewsCategoryID
                          join newsType in dc.NewsTypes on news.NewsTypeID equals newsType.NewsTypeID
                          join newsFormat in dc.NewsFormat on news.NewsFormatID equals newsFormat.NewsFormatID
                          select new News
                                     {
                                         NewsID = news.NewsID,
                                         NewsFormatID = newsFormat.NewsFormatID,
                                         Caption = news.Caption,
                                         Description = news.Description,
                                         Category = newsCategory.Caption
                                     });

            return newsQuery.GroupBy(item => item.Category).Select(item => new NewsCategory
                                                                             {
                                                                                 Caption = item.Key,
                                                                                 News= item.ToList()
                                                                             }).ToList();
        }
    }

..这是有效的。我的问题是,我可以从 POCO 类 News 中删除 NewsCategory 属性,并直接在查询中(连接后)按类别进行分组吗?如何? 提前致谢。

【问题讨论】:

    标签: .net sql linq poco dto


    【解决方案1】:

    您可以在 News POCO 中添加 NewsCategory 属性并使其延迟/显式加载。

    查看this 帖子了解更多详情。

    【讨论】:

    • 我正在使用 Linq2Sql。还有其他想法吗?我仍然想在数据库中按类别对新闻进行分组,并有 List 其中来自 NewsCategory 的 Caption 是我希望对新闻进行分组的属性。
    【解决方案2】:

    此代码演示了如何在执行查询后加载行/列数据并对其进行整形。它不会“在数据库中分组”,但确实允许删除 News.Category 属性。

    var query= (
    from news in dc.News
    from newsCategory in news.NewsCategories
    let newsFormat = news.NewsFormat
    select new //anon type
    {
      NewsID = news.NewsID,
      NewsFormatID = newsFormat.NewsFormatID,
      Caption = news.Caption,
      Description = news.Description,
      Category = newsCategory.Caption
    });
    
    //Load anon rows
    var rows = query.ToList();
    
    //shape the anon rows into our POCSO's.
    List<NewsCategory> result = rows
      .GroupBy(item => item.Category)
      .Select(g => new NewsCategory()
      {
        Caption = g.Key,
        News = g.Select(row => new News()
        {
          NewsID = row.NewsID,
          NewsFormatID = row.NewsFormatID,
          Caption = row.Caption,
          Description = row.Description
        }
      })
      .ToList();
    
    return result;
    

    您不想“在数据库中分组”是有原因的。 group by 的数据库行为是返回键和聚合。您需要键和组元素。为了获取每个组的组元素,linqtosql 将使用每个组的键重新查询数据库。这会导致多次往返(称为 n+1 问题,其中 n 是组数,+1 是获取键的查询)。

    Enumerable.GroupBy 方法返回组键和元素 - 这正是您想要的。

    【讨论】:

    • 如果我理解的话,为了删除 News.Category 属性,我必须创建匿名类型对象,按类别分组,然后绑定到适当的 POCO?
    • 好吧,您不必-必须-使用匿名对象。您也可以声明该对象。是两个映射(查询映射类型 -> 查询结果类型 -> POCO)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-01
    • 2011-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多