带有 subselect 和 groupby 的 LINQ 仅获取列表中每个项目的最新版本
我是 LINQ 的新手...
我有一个 IEnumerable 通用列表,其中包含不同版本的答案(每个版本都有一个问题的 FK)。 从这个列表中我只需要获取最新版本答案的字典。
一个非常简化的类图:
问题
-ID
-问题
- ...其他属性
答案
-ID
-版本
-问题ID
-价值
- ...其他属性
目前我有以下属性:
IEnumerable<Answer> answers = GetAnswers();
IDictionary<long, AnswerDTO> latestVersionAnswers = new Dictionary<long, AnswerDTO>();
if (answers != null)
{
latestVersionAnswers = answers
.OrderBy(e => e.ID)
.GroupBy(e => e.Question.ID)
.Select(g => new AnswerDTO
{
Version = g.Last().Version, // g.Select(e => e.Version).Max(),
QuestionID = g.Key,
ID = g.Last().ID,
Value = g.Last().Value
}).ToDictionary(c => c.QuestionID);
}
虽然这在大多数情况下都有效,但您很快就会发现它需要一些认真的优化(并且有点脆弱,因为它取决于应答记录行顺序而不是“最大”逻辑)。 使用 LINQ 执行此操作的最佳方法是什么,还是最好为每个循环执行多个?
- 如果我只需要版本(而不是 ID、值等),我就不需要 OrderBy,因为我可以直接 g.Select(e => e.Version).Max() (或者我已经现在看到 C# List<> GroupBy 2 Values 上的帖子,但这又会只返回密钥和一个属性:版本)。
- 最终,在这种特殊情况下,我更愿意“过滤”原始列表并返回原始答案项目,而不是涉及 AnswerDTO。
任何指示或帮助将不胜感激!
I'm a newbie when it comes to LINQ...
I have an IEnumerable generic list that contains answers with different versions (each with an FK to the question). From this list I need to get a dictionary of latest version answers only.
A very simplified class diagram:
Question
-ID
-question
- ...other properties
Answer
-ID
-Version
-QuestionID
-Value
- ...other properties
Currently I've got the following :
IEnumerable<Answer> answers = GetAnswers();
IDictionary<long, AnswerDTO> latestVersionAnswers = new Dictionary<long, AnswerDTO>();
if (answers != null)
{
latestVersionAnswers = answers
.OrderBy(e => e.ID)
.GroupBy(e => e.Question.ID)
.Select(g => new AnswerDTO
{
Version = g.Last().Version, // g.Select(e => e.Version).Max(),
QuestionID = g.Key,
ID = g.Last().ID,
Value = g.Last().Value
}).ToDictionary(c => c.QuestionID);
}
While this works for the most part, you can quickly see that it needs some serious optimization (and is a little fragile in that it depends on the Answer record rows order instead of "Max" logic). What would be the best way to do this with LINQ, or is it best to just do multiple for each loops?
- If I only needed the version (and not the ID, Value, etc.) I wouldn't need the OrderBy as I could just go g.Select(e => e.Version).Max() (or I've now seen the post at C# List<> GroupBy 2 Values, but this again would only return the key/s and one property: Version).
- Ultimately, in this particularly situation I would much prefer to just "filter" the original list and return the original answer items instead of involving the AnswerDTO.
Any pointers or help would be much appreciated!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
怎么样....
How about something like....
或者,如果您更喜欢 ToDictionary 的选择重载:
Or, if you prefer the selecting overload of ToDictionary:
我只需重写数据模型以包含当前的答案版本 ID。
I would just rewrite the data model to include the current answer version ID.