【发布时间】:2021-06-03 13:20:33
【问题描述】:
我正在尝试在 Entity Framework Core 的同一查询中使用 in & 和 with
// http://www.albahari.com/nutshell/predicatebuilder.aspx
public static class PredicateBuilder
{
public static Expression<Func<T, bool>> True<T>() { return f => true; }
public static Expression<Func<T, bool>> False<T>() { return f => false; }
public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2)
{
var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
return Expression.Lambda<Func<T, bool>>(Expression.OrElse(expr1.Body, invokedExpr), expr1.Parameters);
}
public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2)
{
var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
return Expression.Lambda<Func<T, bool>>(Expression.AndAlso(expr1.Body, invokedExpr), expr1.Parameters);
}
}
我正在尝试这样的场景
select *
from transaction
where channel = 1
and msisdn = '123123123'
and service in (1, 2, 3)
或
select *
from transaction
where channel = 1
and msisdn = '123123123'
and (service = 1 or service = 2 or service = 3)
private static Expression<Func<Transaction, bool>> CreateSearchPredicate(TransactionSearchQuery search, User user)
{
var predicate = PredicateBuilder.True<Transaction>();
if (search.fk_channel_id > 0)
{
predicate = predicate.And(p => p.fk_channel_id == search.fk_channel_id);
}
// msisdn
if (!string.IsNullOrWhiteSpace(search.msisdn))
{
predicate = predicate.And(p => p.msisdn == search.msisdn);
}
if (search.transactionStates != null && search.transactionStates.Count > 0)
{
var predicateX = PredicateBuilder.True<Transaction>();//also tried with False
foreach (var val in search.transactionStates)
{
predicateX = predicateX.Or(p => p.statusid == val);
}
predicate = predicate.And(predicateX);
}
return predicate;
}
请帮助我 - 我需要在我的 CreateSearchPredicate 中进行哪些更改才能运行 And & In(或同时运行线索)
我的数据库是 mysql 我在存储库中的代码就像
public override IEnumerable<Transaction> GetAll(Expression<Func<Transaction, bool>> predicate)
{
return _context.Set<Transaction>().Include(h => h.ServiceOwner).Include(h => h.TransactionState).Include(h => h.OriginationValidationState).Include(h => h.CommunicationChannel).ThenInclude(h => h.Channel).Where(predicate).AsEnumerable();
//return _context.Set<Transaction>().Where(predicate).AsEnumerable();
}
【问题讨论】:
-
Or绝对应该以false开头,否则true || something始终是true,如您所知。当您“也尝试使用 False”时有什么问题? -
当我尝试使用虚假记录时,没有按标准过滤
-
如果我没有任何过滤器以外的过滤器,我也会收到以下错误,或者我收到错误 LINQ 表达式 'DbSet
.Where(t => True && False || Invoke (p => (Convert(p.statusid, Int32) == __val_0), t[Transaction]) )' 无法翻译。以可翻译的形式重写查询,或通过插入对 AsEnumerable()、AsAsyncEnumerable()、ToList() 或 ToListAsync() 的调用显式切换到客户端评估。请参阅go.microsoft.com/fwlink/?linkid=2101038 了解更多信息。 -
@KamranShahid 你不需要这样的代码来将条件与
And结合起来。只需将Where操作附加到查询中,例如if (idList!=null) { query=query.Where(x=>idList.Contains(x.Id))} -
@KamranShahid 至于存储库代码,您需要多久加载一次包含所有相关实体的整个图表?考虑到如果不首先配置实体就不能使用
Set<>,为什么要使用_context.Transactions而不是_context.Transactions?像 EF Core 这样的 ORM 之上的“通用存储库”是一种反模式。 DbSet 是单实体存储库。 DbContext 是一个多实体的工作单元
标签: mysql entity-framework-core predicatebuilder