C# 滥用“.Select”方法跳过其他循环

C# 滥用“.Select”方法跳过其他循环,c#,entity-framework,linq,entity-framework-core,C#,Entity Framework,Linq,Entity Framework Core,假设下面的代码需要加载附加到实体的导航属性(我只在EF Core中遇到过这个问题,在EF 6中,延迟加载函数可以正常工作) ViewBag.DisplayTags=新字符串(query.ArticlesTags.SelectMany(x=>{ db.Attach(x).Navigation(“Tag”).Load(); 返回x.Tag.Name+“,”; }).ToArray()); 我在select语句中将集合附加到EF跟踪器,然后加载导航属性。我这样做是为了跳过一个额外的for循环 问题是

假设下面的代码需要加载附加到实体的导航属性(我只在EF Core中遇到过这个问题,在EF 6中,延迟加载函数可以正常工作)

ViewBag.DisplayTags=新字符串(query.ArticlesTags.SelectMany(x=>{
db.Attach(x).Navigation(“Tag”).Load();
返回x.Tag.Name+“,”;
}).ToArray());
我在select语句中将集合附加到EF跟踪器,然后加载导航属性。我这样做是为了跳过一个额外的for循环


问题是,尽管跳过另一个循环是一个优势(因为select在内部运行循环),但这种方法是否会导致任何隐藏在我看来的问题?有什么坏处吗?甚至有人推荐它吗

不要这样做。您将对数据库中的每个ArticlesTag运行1个查询。因此,如果ArticlesTags表中有100行,上面的代码将依次对数据库服务器运行101个查询(一个额外的查询用于直接查询ArticlesTags)

以下代码将对ArticleStag列表中的每个项目执行:

Navigation("Tag").Load();
通过查询数据库显式加载单个ArticlesTag上的Tag属性

您可以使用一个Select语句将数据库中的所有名称作为列表获取,然后在内存中使用string.join将它们连接起来。差不多

var names = db.ArticlesTags.Select(x => x.Tag.Name).ToArray();
var displayName = string.Join(", ", names);

更正。它将发出101个查询。SelectMany的内容将针对每个ArticlesTag执行,并向数据库发出另一个查询是的,这就是问题所在。SelectMany正在内存中执行。并且在每次调用SelectMany中的代理时,您都会在调用.Load时向db发出另一个查询。从性能角度来看,这没有什么区别。两者都错了,我认为你在数据访问的基础上遗漏了一些东西。祝你好运…向数据库服务器发出100个查询而不是1个查询从来都不是正确的答案如何查看EF日志并了解它将被传送到什么地方?@Karolis:我不知道该怎么做,你能分享任何关于这个的链接吗?我想这对日志记录会有帮助-
var names = db.ArticlesTags.Select(x => x.Tag.Name).ToArray();
var displayName = string.Join(", ", names);