【问题标题】:Append Filtered Include to Expression将过滤的包含附加到表达式
【发布时间】:2021-01-22 15:21:43
【问题描述】:

在我们的项目中,我们的数据库中存储了多种语言的文本。 我想创建一个在查询中包含文本的辅助函数。

这很有用,因为这种包含在应用程序中经常发生,我希望将包含代码放在一个地方。

包含应使用 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;

【问题讨论】:

  • 您是在谈论(经典 - 完整的 .NET 框架)实体框架 5 - 还是指新的实体框架 Core v5?请在您的帖子正文和您使用的标签中非常清楚!
  • Entity Framework Core v5,抱歉忘记了完整的 .NET 也有 EF 5 版本。

标签: c# entity-framework-core .net-5 linq-expressions


【解决方案1】:

也许这可以工作:

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 的启发来改进。

【讨论】:

  • 谢谢!这行得通,我用另一个问题的代码替换了methodInfo。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多