Conditional Include() in Entity Framework

前端 未结 8 1927
暗喜
暗喜 2020-11-28 09:03

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
                 


        
相关标签:
8条回答
  • 2020-11-28 09:08

    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.

    0 讨论(0)
  • 2020-11-28 09:11

    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();
    
    0 讨论(0)
  • 2020-11-28 09:11

    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)
    
    0 讨论(0)
  • 2020-11-28 09:13

    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();
    
    0 讨论(0)
  • 2020-11-28 09:15

    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);
    

    ?

    0 讨论(0)
  • 2020-11-28 09:21

    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

    0 讨论(0)
提交回复
热议问题