我有这种模型
public class Blog
{
public IList<Post> Posts { get; set; }
}
public class Post
{
public PostType PostType { get; set; }
}
public class PostType
{
public string Code { get; set; } // "Code1" and "Code2"
}
我想要的是,返回所有PostType为 Code1 的博客或无帖子的Blog(假设博客可能没有帖子)
为此,我编写了这个Ef linq查询:
_dbContext.Blogs.Include(b => b.Posts).ThenInclude(b => b.PostType)
.Where(b => b.Posts.Count == 0 || b.Posts.Any(p => p.PostType.Code == "Code1").ToList();
此查询的问题是;如果博客中包含类型为 Code1 和 Code2 的帖子,则上面的查询将同时包含代码 Code2 和 Code1 的帖子因为我正在使用 Any 。
所以我尝试了这个:我使用的是 All
,而不是 Any_dbContext.Blogs.Include(b => b.Posts).ThenInclude(b => b.PostType)
.Where(b => b.Posts.Count == 0 || b.Posts.All(p => p.PostType.Code == "Code1").ToList();
但是在上述情况下,此查询不返回任何内容。
在给定的情况下,有一种方法可以使用单个返回所有帖子类型为代码1 的博客,而无需包括帖子类型为 Code2 的博客是linq查询吗?
答案 0 :(得分:2)
该解决方案类似于Thierry V的解决方案,除了将过滤后的帖子存储在单独的词典中以避免EF跟踪副作用:https://docs.microsoft.com/en-us/ef/core/querying/tracking。
但是,我真的看不到这些代码背后的原因。通常,您会获取所有满足您条件的博客(包含Code1的任何帖子),然后根据需要对其进行过滤。
var blogs = _dbContext.Blogs.Include(b => b.Posts).ThenInclude(b => b.PostType)
.Where(b => b.Posts.Count == 0 || b.Posts.Any(p => p.PostType.Code == "Code1")
.ToList();
// Storing the filterd posts in a dictionary to avoid side-effects of EF tracking.
var dictionary = new Dictionary<int, List<Post>>();
foreach (var blog in blogs) {
dictionary[blog.BlogId] = blog.Posts.Where(p => p.PostType.Code == "Code1").ToList();
}
答案 1 :(得分:1)
var blogs = _dbContext.Blogs.Include(b => b.Posts).ThenInclude(b => b.PostType)
.Where(b => b.Posts.Count == 0 || b.Posts.Any(p => p.PostType.Code == "Code1").ToList();
// blogs contains posts which have Code1, and maybe Code2
//filter the posts by assigning only the posts with Code1
blogs.ForEach(b=> b.Posts = b.Posts.Where( p => p.PostType.Code == "Code1"))