我总是发现自己正在创建仍然大量使用嵌套的foreach循环的linq表达式。下面是我正在谈论的一个简单示例,如果有人在这里可以告诉我如何将这个低效率代码压缩成单个linq表达式,我真的很感激吗?
数据库上下文(db)有三个表:Blog,Tag,Junc_Tag_Blog。联结表只是存储博客及其标签的记录。
无论如何,这是我凌乱的代码:
public static Collection<Blog> GetByTag(string tagName)
{
// Get the tag record.
var tag = (from t in db.Tags
where t.Name == tagName
select t).Single();
// Get the list of all junction table records.
var tagJunc = from tj in db.Junc_Tag_Blogs
where tj.Fk_Tag_Id == tag.Id
select tj;
// Get a list of all blogs.
var blogs = from b in db.BlogPosts
select b;
// Work out if each blog is associated with given tag.
foreach(var blog in blogs)
{
foreach(var junc in tagJunc)
{
if(blog.Id == junc.Fk_Blog_Id)
{
// We have a match! - do something with this result.
}
}
}
}
提前感谢能帮我清理此代码的人!
答案 0 :(得分:4)
您可以构建一个查询,让数据库为您找到匹配项。
List<Blog> blogs =
(
from t in tag
where t.Name == tagName
from tj in t.Junc_Tag_Blogs
let b = tj.Blog
select b
).ToList();
答案 1 :(得分:1)
var blogsWithGivenTag =
from blog in db.BlogPosts
where blog.BlogTags.Any(bt => bt.Tag.Name == tagName)
select blog;
答案 2 :(得分:0)
答案 3 :(得分:0)
您可以将博客放入字典中,将博客ID上的联结分组,然后遍历这些组:
var blogDict = blogs.ToDictionary(b => b.Id);
foreach(var group in tagJunk.GroupBy(j => j.Fk_Blog_Id)) {
if (blogDict.ContainsKey(group.Key)) {
var blog = blogDict[group.Key];
foreach (var junction in group) {
// here you have the blog and the junction
}
}
}
这也是嵌套循环,但对于每个博客,您只能遍历实际属于该博客的联结,而不是所有联结。