I have seen a few answers to similar questions, however I cannot seem to work out how to apply the answer to my issue.
var allposts = _context.Posts
You can use this implementation of an extension method (eg.) Include2()
. After that, you can call:
_context.Posts.Include2(post => post.Attachments.Where(a => a.OwnerId == 1))
The code above includes only attachments where Attachment.OwnerId == 1
.
try this
var allposts = _context.Posts
.Include(p => p.Comments)
.Include(a => a.PostAuthor)
.Where(t => t.PostAuthor.Id == postAuthorId).ToList();
_context.Attachments.Where(o=>o.Owner is Author).ToList();
Assuming "a" being of type "YourType", a conditonal include could be solved by using a method extension, e.g.
public static class QueryableExtensions
{
public static IQueryable<T> ConditionalInclude<T>(this IQueryable<T> source, bool include) where T : YourType
{
if (include)
{
return source
.Include(a => a.Attachments)
.Include(a => a.Attachments.Owner));
}
return source;
}
}
... then just use this like you are using .Include, e.g.
bool yourCondition;
.ConditionalInclude(yourCondition)
From the link you posted I can confirm that trick works but for one-many (or many-one) relationship only. In this case your Post-Attachment
should be one-many relationship, so it's totally applicable. Here is the query you should have:
//this should be disabled temporarily
_context.Configuration.LazyLoadingEnabled = false;
var allposts = _context.Posts.Where(t => t.PostAuthor.Id == postAuthorId)
.Select(e => new {
e,//for later projection
e.Comments,//cache Comments
//cache filtered Attachments
Attachments = e.Attachments.Where(a => a.Owner is Author),
e.PostAuthor//cache PostAuthor
})
.AsEnumerable()
.Select(e => e.e).ToList();
Lambda in Include()
may only point to a property:
.Include(a => a.Attachments)
.Include(a => a.Attachments.Owner);
Your condition doesn't makes sense for me because Include()
means join
and you either do it or not. And not conditionally.
How would you write this in raw SQL?
Why not just this:
context.Attachments
.Where(a => a.Owner.Id == postAuthorId &&
a.Owner.Type == authorType);
?
EF Core 5.0 is introducing Filtered Include soon.
var blogs = context.Blogs
.Include(e => e.Posts.Where(p => p.Title.Contains("Cheese")))
.ToList();
Reference: https://docs.microsoft.com/en-us/ef/core/what-is-new/ef-core-5.0/whatsnew#filtered-include