将实体框架查询结果放入嵌套字典的有效方法?

发布于 2024-11-09 13:54:11 字数 1871 浏览 0 评论 0原文

我不知道如何解决这个问题。我正在编写一个函数,我希望返回类型为:

Dictionary(Of String, Dictionary(Of Integer, List(Of Article)))

我基本上得到了一个我想要按学期名称分组的文章列表,然后按月份值分组,然后按适合该分组的文章列表分组。

到目前为止,我已经能够做到这一点:

Dim lectures As New Dictionary(Of Integer, List(Of Article))
        lectures = (From Articles In db.Articles _
           Order By Articles.StartDate.Value.Month Ascending _
           Where Articles.ArtType = ArticleConstants.lecturesTypeId _
           Group By Articles.StartDate.Value.Month _
           Into Group).AsEnumerable().Reverse.ToDictionary(Function(x) x.Month, Function(x) x.Group.ToList())

这给了我内部字典,但是我不知道从这里去哪里。由于我仅将月份存储为整数,因此我无法使用它来可靠地确定学期(因为学期是“2011 年秋季”)。我也无法获取完整的日期,因为那样我的分组就无法工作。

我有一项服务可以根据文章的开始日期获取学期,如下所示:

SemesterService.getSemester(Article.StartDate)

但我再次不确定如何应用它。我想也许我只是从给定日期范围内的所有文章开始,然后根据迭代这些结果的某些逻辑手动填充内部和外部字典,但我以前从未做过如此复杂的事情,而且我遇到了麻烦。

所以最后我会得到一个如下所示的结果集:

Fall 2011 (outer dictionary key)
    1 (for January, inner dictionary key)
        Article 1
        Article 2 (list of articles, inner dictionary value)
        Article 3

有人能帮我吗?

编辑:我愿意使用不同的返回类型,只要它以类似的方式嵌套和分组数据即可。

学期根本不是存储在数据库中的对象。它只是我根据日期填充的静态对象,因此我无法通过该对象进行查询。我只是在数据库中有我的文章,它有一个与之关联的开始日期,并且使用该开始日期我可以计算它所在的学期。

编辑:尝试了下面的 usr 解决方案:

From Articles In db.Articles _
   Order By Articles.StartDate.Value.Month Ascending _
   Where Articles.ArtType = ArticleConstants.lecturesTypeId _
   Group New With { Articles, .Semester = SemesterService.getSemester(Articles.StartDate) } By Articles.StartDate.Value.Month _
   Into Group

执行此操作时,我收到错误:LINQ to Entities 无法识别“Semester getSemester(System.DateTime)”方法,并且此方法无法转换为存储表达式。

它似乎真的很讨厌按您在查询中计算的内容进行分组,但是不在原始数据集中。

I'm hitting a loss at how to approach this problem. I am writing a function where I want the return type to be:

Dictionary(Of String, Dictionary(Of Integer, List(Of Article)))

I've basically got a list of articles that I wanted grouped by semester name, then by month value, then by the list of articles that fit into that.

So far I have been able to do this:

Dim lectures As New Dictionary(Of Integer, List(Of Article))
        lectures = (From Articles In db.Articles _
           Order By Articles.StartDate.Value.Month Ascending _
           Where Articles.ArtType = ArticleConstants.lecturesTypeId _
           Group By Articles.StartDate.Value.Month _
           Into Group).AsEnumerable().Reverse.ToDictionary(Function(x) x.Month, Function(x) x.Group.ToList())

And this gets me the inner dictionary, however I am not sure where to go from here. Since I am only storing the month as an integer, I can't use that to reliably determine the semester (as a semester is "Fall 2011"). I also can't grab the full date because then my grouping wouldn't work.

I have a service to get the semester based on the Article's startDate that looks like this:

SemesterService.getSemester(Article.StartDate)

But again I am not sure how to apply this. I am thinking maybe I just start with all the articles in a given date range and then manually populate both the inner and outer dictionaries based on some logic which iterates through those results, but I have never done something this complex before and I am having trouble.

So in the end I would have a result set that looks like:

Fall 2011 (outer dictionary key)
    1 (for January, inner dictionary key)
        Article 1
        Article 2 (list of articles, inner dictionary value)
        Article 3

Can anyone help me out?

EDIT: I am open to using a different return type, as long as it nests and groups data in a similar fashion.

Semester is NOT an object stored in the database at all. It's just a static object I populate based on the date, so I cannot query by that. I just have my articles in the database, which has a startdate associated with it, and using that startdate I can calculate the semester it's in.

Edit: Tried usr's solution below which is:

From Articles In db.Articles _
   Order By Articles.StartDate.Value.Month Ascending _
   Where Articles.ArtType = ArticleConstants.lecturesTypeId _
   Group New With { Articles, .Semester = SemesterService.getSemester(Articles.StartDate) } By Articles.StartDate.Value.Month _
   Into Group

Upon doing this I get an error: LINQ to Entities does not recognize the method 'Semester getSemester(System.DateTime)' method, and this method cannot be translated into a store expression.

It just seems to really hate grouping by something you calculate in the query but isn't in the original dataset.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

飘然心甜 2024-11-16 13:54:11

我将用伪 C# 回答:

from s in semesters
group s by s.Name into g
select new {
 SemName = g.Key,
 MonthsItems = (from y in g group y by y.Month into g2 select new { Month = g2.Key, ... }
}

这就是进行嵌套分组的方式。然而!这将产生令人沮丧的糟糕性能。请务必将“semesters”替换为“semesters.AsEnumerable()”,以便在客户端上评估嵌套分组。 SQL 无法返回树,因此无法在服务器上完成此操作。希望这对您有所帮助,如果不清楚,请发表评论,我会详细说明。

作为替代方案,请执行以下操作:

from s in semesters
group s by new { s.Name, s.Month }

这样您就可以在服务器上完全执行。

编辑:从评论中我可以看出问题是不同的。

       From Articles In db.Articles _
       Order By Articles.StartDate.Value.Month Ascending _
       Where Articles.ArtType = ArticleConstants.lecturesTypeId _
       Group new { Articles, Semester = SemesterService.getSemester(Articles.StartDate) } By Articles.StartDate.Value.Month _
       Into Group

请注意,分组依据功能允许有两个参数而不是一个。您不仅可以指定分组列,还可以指定每个组中想要包含的值。在这种情况下,我不仅指定按月对文章进行分组,而且还保留它们的学期。乔普这有帮助。

I will answer in pseudo-C#:

from s in semesters
group s by s.Name into g
select new {
 SemName = g.Key,
 MonthsItems = (from y in g group y by y.Month into g2 select new { Month = g2.Key, ... }
}

This is how you do a nested grouping. However! This will yield depressingly bad perf. Be sure do replace "semesters" with "semesters.AsEnumerable()" to cause the nested grouping to be evaluated on the client. SQL does not have the ability to return trees so this cannot be done on the server. Hope this helps, if unclear, comment and I will elaborate.

As an alternative, do this:

from s in semesters
group s by new { s.Name, s.Month }

That way you can execute fully on the server.

Edit: From the comments I can tell the problem is something different.

       From Articles In db.Articles _
       Order By Articles.StartDate.Value.Month Ascending _
       Where Articles.ArtType = ArticleConstants.lecturesTypeId _
       Group new { Articles, Semester = SemesterService.getSemester(Articles.StartDate) } By Articles.StartDate.Value.Month _
       Into Group

Notice that the group by feature allows to to have two paramters not one. You can not only specify the grouping columns but also the values you want to have in each group. In this case I specified to group by month not only the articles but to also retain their semesters. Jope this helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文