c# - 如何在 n-n 关系中获得最频繁重复的对象?

标签 c# asp.net-mvc entity-framework c#-4.0 entity-framework-6

我有这两个实体(在 C# 和 EntityFramework 中):

public class Article 
{ 
    public int Id { get; set; }
    public IList<Tag> Tags { get; set; }
}

public class Tag 
{
    public int Id { get; set; }
    public IList<Article> Articles { get; set; }
}

具有n-n关系。我正在加载我的文章,就像您在这段代码中看到的那样简单:

var model = _context.Articles
                    .AsNoTracking()
                    .Include(a => a.Tags)
                    .ToList();

现在,我试图通过以下片段获取文章中重复次数最多的标签:

var tags = model.SelectMany(a => a.Tags)
                .GroupBy(t => new { t.Name, t.Articles })
                .OrderByDescending(g => g.Count())
                .Take(10);

但它似乎不起作用(我得到的所有标签的 Count = 1)。我在这里错过了什么?有什么想法吗?提前致谢。

最佳答案

回答您的具体问题:

But it seems doesn't work (I'm getting Count = 1 for all tags). What am I missing here?

这是因为您已将 tag.Articles 包含在分组键中。如果具有相同 IdTag 对象共享同一个实例,通常不会有问题(除了冗余和不必要的比较)。但是由于您已使用无跟踪查询 (.AsNoTracking()) 填充了 model,因此代表同一条记录的 Tag 对象实际上是不同的实例(数据重复),它们的 Articles 列表也是如此,因此 group by 无法按预期工作。可以通过以下代码片段轻松看出:

foreach (var tagGroup in model.SelectMany(a => a.Tags).GroupBy(t => t.Id))
{
    Tag prevTag = null;
    foreach (var tag in tagGroup)
    {
        if (prevTag != null) Debug.Assert(prevTag == tag); // FAIL!
        prevTag = tag;
    }
}

要解决此问题,请删除 AsNotracking 或从分组键中排除 Articles:

var tags = model.SelectMany(a => a.Tags)
                .GroupBy(t => t.Id) // or Name
                .OrderByDescending(g => g.Count())
                .Take(10);

关于c# - 如何在 n-n 关系中获得最频繁重复的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39892629/

相关文章:

c# - 在打开列标识的情况下插入行时使用 SqlCeCommandBuilder 时出错

asp.net-mvc - 在 ASP.NET MVC 中更新多个模型

c# - 在 Entity Framework 中区分 MySQL 和 SQL Server

c# - 测试 Entity Framework 模型

c# - 将键/值对列表转换为数据表

c# - 如何显示具有焦点外观但不焦点的表单?

c# - 如何使用 C# 中的参数获取和设置 vb6 属性?

c# - 集合上的表达式树 'Any'

c# - Linq .GroupBy() 与计数

c# - EF Code First 实现接口(interface)属性