LINQ中的条件GroupBy()

Ran*_*ger 5 c# linq guid matrix

我正在处理一个充满项目之间相似性的矩阵.我将这些保存为数据库中的对象列表.Similarity对象如下所示:

public class Similarity
{
    public virtual Guid MatrixId { get; set; } //The id of the matrix the similarity is in
    public virtual Guid FirstIndex { get; set; } //The id of the item of the left side of the matrix
    public virtual Guid SecondIndex { get; set; } //The id of the item of the top side of the matrix
    public virtual double Similarity { get; set; } //The similarity
}
Run Code Online (Sandbox Code Playgroud)

用户可以查看这些项目.我想要检索与用户已审阅的项目"相似"的项目列表.问题是我无法确定该项目的ID是否在FirstIndexSecondIndex.我写了一些代码,它可以完成我想要的,但我想知道这是否可以在1个语句中实现.

var itemsNotReviewed = Similarities.Where(x => !itemsReviewed.Contains(x.SecondIndex))
    .GroupBy(x => x.SecondIndex)
    .ToList();
itemsNotReviewed.AddRange(Similarities.Where(x => !itemsReviewed.Contains(x.FirstIndex))
     .GroupBy(x => x.FirstIndex)
     .ToList());
Run Code Online (Sandbox Code Playgroud)

itemsReviewed用户已审阅的项目的guid列表在哪里?哪里是与用户已审阅Similarities的项目类似的所有项目的列表.我用这个函数检索该列表:

return (from Row in _context.SimilarityMatrix
        where itemIds.Contains(Row.FirstIndex) || itemIds.Contains(Row.SecondIndex)
        select Row)
        .Distinct()
        .ToList();
Run Code Online (Sandbox Code Playgroud)

其中itemIds是用户已审阅的项目的guid列表.

有没有办法根据Where子句分组第一个或第二个索引?

如果我要详细说明,请告诉我!

Iva*_*oev 4

据我了解,您有一个列表,其中Similarity保证包含FirstIndexSecondIndex包含在itemsReviewed列表中的项目Guid并且您需要获取未包含在其中任一索引的元素(如果有)itemsReviewed(由于第一个约束,它可能只是其中一个)并按该索引进行分组。

上述内容的简单 LINQ 翻译如下:

var itemsNotReviewed = Similarities
    .Where(item => !itemsReviewed.Contains(item.FirstIndex) || !itemsReviewed.Contains(item.SecondIndex))
    .GroupBy(item => !itemsReviewed.Contains(item.FirstIndex) ? item.FirstIndex : item.SecondIndex)
    .ToList();
Run Code Online (Sandbox Code Playgroud)

但它包含重复的itemsReviewed.Contains检查,这会对性能产生负面影响。

因此,更好的变体是引入中间变量,最简单的方法是查询语法和let子句:

var itemsNotReviewed =
    (from item in Similarities
     let index = !itemsReviewed.Contains(item.FirstIndex) ? 1 :
            !itemsReviewed.Contains(item.SecondIndex) ? 2 : 0
     where index != 0
     group item by index == 1 ? item.FirstIndex : item.SecondIndex)
    .ToList();
Run Code Online (Sandbox Code Playgroud)