Reputation: 9265
EF Core has support for explicit loading. The context has two overloads, one for references and one for collections.
Having two methods is not useful, and gets messy. I want a single method for accepting both as a params array.
So instead of this
await context.Entry(customer).Collection(e => e.Orders).LoadAsync();
await context.Entry(customer).Collection(e => e.Returns).LoadAsync();
await context.Entry(customer).Reference(e => e.Account).LoadAsync();
I want to do this:
await context.Entry(customer).Load(e=>e.Orders, e=>e.Returns, e=>e.Account);
I assume this is possible, because there is something similar with context.Include(...)
which accepts both collections and references.
In my context class, I have this so far:
public async Task Load<TEntity>(TEntity entity, params Expression<Func<TEntity, object>>[] propertyExpressions)
where TEntity : class
{
foreach (var propertyExpression in propertyExpressions) {
var isCollection = typeof(IEnumerable).GetTypeInfo()
.IsAssignableFrom(propertyExpression.Body.Type);
if(isCollection)
{
await Entry(entity)
.Collection(propertyExpression) // problem is here !!!!!
.LoadAsync();
}
else
{
await Entry(entity)
.Reference(propertyExpression)
.LoadAsync();
}
}
}
The problem line is shown above. The input is object
but .Collection()
expects IEnumerable<TProperty>
.
How do I make this work?
Upvotes: 2
Views: 1253
Reputation: 205589
Taking into account that both methods return NavigationEntry
derived class, and both use Microsoft.EntityFrameworkCore.Internal.ExpressionExtensions.GetPropertyAccess
method to get the PropertyInfo.Name
from the passed lambda expression, you can use the same approach to retrieve the name and then use the Navigation
method:
using Microsoft.EntityFrameworkCore.Internal;
public async Task Load<TEntity>(TEntity entity, params Expression<Func<TEntity, object>>[] propertyExpressions)
where TEntity : class
{
foreach (var propertyExpression in propertyExpressions)
{
var propertyName = propertyExpression.GetPropertyAccess().Name;
await Entry(entity).Navigation(propertyName).LoadAsync();
}
}
Upvotes: 5