简体   繁体   中英

How can I implement multiple Include in Entity Framework?

I use Entity framework 6. I have a Transaction object with several navigation properties. It is easy to implement eager loading using multiple Include.

 var aa = db.Transactions.Include(p => p.Account).Include(p => p.Instrument);

How can I implement the same if the fields to be included are parameters?

var aa = db.Transactions.IncludeMore(delegatesToBeIncluded);   

If delegatesToBeIncluded is null then there is nothing to be included.

https://stackoverflow.com/a/38823723/5852947 This is similar what I want but it uses string instead of delegates.

https://stackoverflow.com/a/35889204/5852947 This is also interesting.

How to pass lambda 'include' with multiple levels in Entity Framework Core? This focuses on multiple level (I have one level)

https://stackoverflow.com/a/52156692/5852947 This is promising also.

Which direction should I go?

Revision 1 : Why I need this? Based on the elements of aa new objects will be created. I realized that at each object creation EF reads the DB (lazy loading is used). It is just 50 ms, but it is repeated n times. This function is implemented in a template class, so Transactions is also a parameter.

Revision 2 : In the full code there is filtering (pagination to be exact), and ToList() at then end. The tricky part that it is implemented in a template function. dbTableSelector is a delegate: readonly Func<MainDbContext, DbSet<TDbTable>> dbTableSelector;

 var myList = dbTableSelector(db).Where(WhereCondition).
             Skip(numberOfSkippedRows).Take(PageSize).OrderBy(OrderByCondition).ToList();

After that I transform each element of myList to another type of object. This is where lazy loading is activated one by one for each element. That is why I try to use Include. If dbTableSelector(db) returns Transactions I have to Include different elements when it returns let us say Instruments . So IncludeMore should have a List parameter which defines the fields to be included.

Here is the solution. It is based on this .

public static class IQueryableExtensions
{
    public static IQueryable<T> IncludeMultiple<T, TProperty>(this IQueryable<T> query,
        Expression<Func<T, TProperty>>[] includeDelegates) where T : class
    {
        foreach (var includeDelegate in includeDelegates)
            query = query.Include(includeDelegate);
        return query;
    }
}

This is the calling:

var pathsA = new Expression<Func<ViewTransaction, object>>[2] { p => p.Account, p => p.Instrument };
var pathsB = new Expression<Func<ViewTransaction, object>>[1] { p => p.Account};
var pathsC = Array.Empty<Expression<Func<ViewTransaction, object>>>();


var a = db.ViewTransactions.IncludeMultiple(pathsA).Single(e => e.Id == 100);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM