Я могу как-то воспользоваться совместно FindAsync и Include?
В общем, есть Generic-метод, который по ключу возвращает сущность:
`await context.Set<T>().FindAsync(key, token)`
, а снаружи принимает id, который является типом object, который я привожу в коде к ключу:
var key = id is object[] objects ? objects : new[] {id};
Эта штука работает, но проблема в том, что мне теперь понадобилось так же подгружаться данные к этой сущности через навигационные свойства.
Когда я добавляю Include, то я теряю возможность пользоваться удобным для себя FindAsync.
Через context.Entry(T).Reference()- это, вроде, геморнее делается, если мне еще потребуется идти в глубь, а в Include, как я понимаю, такой проблемы нет.
Какие есть решения проблемы?
Ответы (1 шт):
В общем, сделал так:
Метод, который по некоторой конфигурации "обогащает" набор данных Include:
public IQueryable<T> Ecrich<T>(DbSet<T> dbSet) where T : class
{
var config = _navPropLoaderProfile.NavigationDictionary[typeof(T)];
var query = dbSet.AsQueryable();
return config.NavPropNames.Aggregate(query, (current, nav) => current.Include(nav));
}
Методы которыми я генерю условие и получаю желаемый результат:
public async Task<T> GetOldObjectAsync<T>(T entity, CancellationToken token = default) where T : class
{
using (var context = _contextFactory.Create())
{
var key = GetKey<T>(context);
return await _navPropEnrichService.Ecrich(context.Set<T>()).FirstOrDefaultAsync(BuildCondition(key, entity), token);
}
}
private IEnumerable<PropertyInfo> GetKey<T>(DbContext context)
{
return context.Model.FindEntityType(typeof(T)).FindPrimaryKey().Properties.Select(x => x.PropertyInfo);
}
private Expression<Func<T, bool>> BuildCondition<T>(IEnumerable<PropertyInfo> keyProps, T entity)
{
var param = Expression.Parameter(typeof(T));
Expression cond = null;
foreach (var prop in keyProps)
{
var equalExpr = Expression.Equal(Expression.Property(param, prop), Expression.Constant(prop.GetValue(entity)));
cond = cond == null ? equalExpr : Expression.And(cond, equalExpr);
}
return Expression.Lambda<Func<T, bool>>(cond, param);
}
Критика и рекомендации приветствуются.