C# 为什么此列表中存在排序错误?
我在图像和图像标签系统中有这些模型:C# 为什么此列表中存在排序错误?,c#,asp.net-core,entity-framework-core,ef-core-3.0,C#,Asp.net Core,Entity Framework Core,Ef Core 3.0,我在图像和图像标签系统中有这些模型: public class Image { public int Id { get; set; } // some more properties... public List<ImageTag> Tags { get; set; } } public class ImageTag { public int Id { get; set; } public int ImageId { get; set; }
public class Image
{
public int Id { get; set; }
// some more properties...
public List<ImageTag> Tags { get; set; }
}
public class ImageTag
{
public int Id { get; set; }
public int ImageId { get; set; }
public string Tag { get; set; }
public Image Image { get; set; }
}
公共类映像
{
公共int Id{get;set;}
//更多属性。。。
公共列表标记{get;set;}
}
公共类ImageTag
{
公共int Id{get;set;}
公共int-ImageId{get;set;}
公共字符串标记{get;set;}
公共映像映像{get;set;}
}
要获得前10个最常用标记的列表,我运行以下查询:
List<ImageTag> mostUsedTags =
await db.Images
.Select(t => t.Tags.OrderBy(o => o.ImageId).FirstOrDefault()).Take(10)
.ToListAsync().ConfigureAwait(false);
// The list has the tags with the fewest images first, so I have to reverse it:
mostUsedTags.Reverse();
列出mostUsedTags=
等待数据库图像
.Select(t=>t.Tags.OrderBy(o=>o.ImageId.FirstOrDefault()).Take(10)
.ToListSync().ConfigureAwait(false);
//列表中首先有图像最少的标记,因此我必须将其反转:
mostUsedTags.Reverse();
我得到的列表中有以下数量的图像与之关联:4、3、2、1、2、1、1
为什么第四名和第五名交换了位置
列表中首先有图像最少的标签,所以我必须
倒过来:
您的假设是不正确的,在选择第一个元素之前,以下命令将按ImageId
标记,然后按其选择的任何顺序返回列表
t.Tags.OrderBy(o => o.ImageId)
我“猜测”你想要这样的东西,虽然我不完全确定我确切地理解你想要什么
.Images.OrderByDescending(x => x.Tags.Count)
.Select(t => ...)...
或许
ImageTags.GroupBy(x => x.ImageId)
.OrderByDescending(x => x.Count)
.Select(t => ...)
.Take(10)
我不太清楚如何确定一个标记是否被多个图像使用,因为这两个类之间的映射似乎有点“混乱”(正如我在问题下方的评论中所描述的)
但是假设Tag
属性是我们用来查看两个ImageTag
对象是否相同的属性,那么您可以这样做来获得最常用的标记:
var mostUsedTags = images
.SelectMany(i => i.Tags) // Get all the ImageTags from all the images
.GroupBy(t => t.Tag) // Group them by the Tag property
.OrderByDescending(g => g.Count()) // Order groups by their count (descending)
.Take(10) // Take the top 10 results
.Select(g => g.Count()); // Select the count associated with each tag
您还可以选择一个提到标记的字符串
,这样您就可以知道哪些标记最受欢迎:
.Select(g => $"'{g.Key}' is associated with {g.Count()} images");
或者只需将.Select()
替换为.ToList()
,即可获得所有i分组
对象本身的列表,这样您就拥有了与每个组相关的所有数据在选择第一个组之前,您正在对每个图像持有的图像标记进行排序。您没有对图像本身进行排序。您的类似乎过度绑定在一起,并且具有一些冗余属性。此外,还不清楚如何区分哪些标签是唯一的。您的图像
有一个图像标签
列表,而图像标签
有一个图像
和一个图像ID
。这似乎是一个非常糟糕的设计,因为ImageTag
可以添加到Image.Tags
列表中,但是ImageTag
本身可以在其Image
属性上设置一个完全不同的Image
,它还可以为它的ImageId
属性设置另一个完全不同的Image.Id
。@RufusL所说的可能是核心问题。我猜你的数据中有N:M关系。图像标签到图像?这听起来像是一个经典的N:M关系。N:M必须使用一个中间表/类型来解决,它将其转换为两个1:N关系。然后您就可以使用它了。@RufusL这对于具有一对多FK关系的EF或EF核心模型类来说是相当标准的,所以这里不必担心。框架使用这些属性来构建具有联接的SQL查询,并且在实现查询结果时也始终保持它们。如果其中一个答案已经解决了您的问题,最好将其标记为未来读者所接受的,否则,您可能会考虑用新的信息和新的发现以及为什么它们不工作来更新问题。所以其他人可以回答谢谢。这很有效。但是有没有办法避免先加载所有的图像
s,然后再处理该集合?现在数据库只包含几个图像已经很好了,但是如果它包含数千个图像,它会不会明显变慢,因为我们正在加载所有图像,然后丢弃大部分图像?如果您有其他图像标记源,您可以使用它。