将过滤后的包含附加到表达式
Append Filtered Include to Expression
在我们的项目中,我们的数据库中存储了多种语言的文本。
我想创建一个在查询中包含文本的辅助函数。
这会很有用,因为这种包含在应用程序中经常发生,我希望将包含代码放在一个地方。
包含应该使用 Entity Framework Core 5 中的 the new filtered includes。
这是我要替换的:
.Include(c => c.NameTexts.Where(t => t.LanguageId == langId))
替换为:
.IncludeText(e => e.NameTexts, langId)
我要写的功能:
// The helper function:
public static IQueryable<T> IncludeText<T>(this IQueryable<T> originalQuery, Expression<Func<T, IEnumerable<UserText>>> textToInclude, int langId) where T : class
{
var textWhere = textToInclude.Where(e => e.LanguageId == langId);
originalQuery.Include(textWhere);
return originalQuery;
}
// And call it from a query like this:
var result = await _context.SomeEntity
.IncludeText(e => e.NameTexts, langId)
// Instead of
// .Include(c => c.NameTexts.Where(t => t.LanguageId == langId))
.Where(c => c.Id == request.Id)
.SingleOrDefaultAsync(cancellationToken);
我尝试执行以下操作但出现错误,因为类型不匹配。
Expression<Func<UserText, bool>> newPred = t => t.LanguageId == langId;
var textWhere = Expression.Lambda<Func<T, IList<UserText>>>(Expression.AndAlso(textToInclude, newPred), textToInclude.Parameters);
originalQuery.Include(textWhere);
return originalQuery;
也许这行得通:
public static IQueryable<T> IncludeText<T>(this IQueryable<T> originalQuery, Expression<Func<T, IEnumerable<UserText>>> textToInclude, int langId) where T : class
{
var methodWhere = typeof(Enumerable)
.GetMethods()
.First(m => m.ToString() == "System.Collections.Generic.IEnumerable`1[TSource] Where[TSource](System.Collections.Generic.IEnumerable`1[TSource], System.Func`2[TSource,System.Boolean])")
.MakeGenericMethod(typeof(UserText));
Expression<Func<UserText, bool>> predicate = t => t.LanguageId == langId;
var navigationWhere = Expression.Call(methodWhere, textToInclude.Body, predicate);
var lambda = Expression.Lambda<Func<T, IEnumerable<UserText>>>(navigationWhere, Expression.Parameter(typeof(T)));
return originalQuery.Include(lambda);
}
我不喜欢 Where
MethodInfo 的恢复方式。您可以通过其他 question.
的启发来改进
在我们的项目中,我们的数据库中存储了多种语言的文本。 我想创建一个在查询中包含文本的辅助函数。
这会很有用,因为这种包含在应用程序中经常发生,我希望将包含代码放在一个地方。
包含应该使用 Entity Framework Core 5 中的 the new filtered includes。
这是我要替换的:
.Include(c => c.NameTexts.Where(t => t.LanguageId == langId))
替换为:
.IncludeText(e => e.NameTexts, langId)
我要写的功能:
// The helper function:
public static IQueryable<T> IncludeText<T>(this IQueryable<T> originalQuery, Expression<Func<T, IEnumerable<UserText>>> textToInclude, int langId) where T : class
{
var textWhere = textToInclude.Where(e => e.LanguageId == langId);
originalQuery.Include(textWhere);
return originalQuery;
}
// And call it from a query like this:
var result = await _context.SomeEntity
.IncludeText(e => e.NameTexts, langId)
// Instead of
// .Include(c => c.NameTexts.Where(t => t.LanguageId == langId))
.Where(c => c.Id == request.Id)
.SingleOrDefaultAsync(cancellationToken);
我尝试执行以下操作但出现错误,因为类型不匹配。
Expression<Func<UserText, bool>> newPred = t => t.LanguageId == langId;
var textWhere = Expression.Lambda<Func<T, IList<UserText>>>(Expression.AndAlso(textToInclude, newPred), textToInclude.Parameters);
originalQuery.Include(textWhere);
return originalQuery;
也许这行得通:
public static IQueryable<T> IncludeText<T>(this IQueryable<T> originalQuery, Expression<Func<T, IEnumerable<UserText>>> textToInclude, int langId) where T : class
{
var methodWhere = typeof(Enumerable)
.GetMethods()
.First(m => m.ToString() == "System.Collections.Generic.IEnumerable`1[TSource] Where[TSource](System.Collections.Generic.IEnumerable`1[TSource], System.Func`2[TSource,System.Boolean])")
.MakeGenericMethod(typeof(UserText));
Expression<Func<UserText, bool>> predicate = t => t.LanguageId == langId;
var navigationWhere = Expression.Call(methodWhere, textToInclude.Body, predicate);
var lambda = Expression.Lambda<Func<T, IEnumerable<UserText>>>(navigationWhere, Expression.Parameter(typeof(T)));
return originalQuery.Include(lambda);
}
我不喜欢 Where
MethodInfo 的恢复方式。您可以通过其他 question.