【问题标题】:LINQ Expression AndAlso with Nullable typeLINQ 表达式 AndAlso 与 Nullable 类型
【发布时间】:2017-04-06 06:19:42
【问题描述】:

我正在使用 LINQ 表达式生成一个 where 条件。

我的实体如下;

public class Sample
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int AnotherId { get; set; }
    public int? RelationId { get; set; }
}

我必须根据两个键过滤数据,即AnotherIdRelationId.RelationId(可选)。所以在我的方法参数relationId可能不会更新为0。

基于此我需要生成一个表达式:

Expression<Func<Sample, bool>> condition = x => x.AnotherId == anotherId;
if (relationId > 0)
{
    Expression<Func<Sample, bool>> additionalCondition = x => x.RelationId == relationId;
    condition = Expression.Lambda<Func<Sample, bool>>(Expression.AndAlso(condition, additionalCondition), condition.Parameters);
}

这里我在AndAlso 语句中得到了以下异常:

没有为“System.Func`2[Sample,System.Boolean]”和“System.Func`2[Sample,System.Boolean]”类型定义二元运算符 AndAlso。

请帮我纠正我的问题。

【问题讨论】:

  • 查看this链接
  • 我认为condition = Expression.Lambda&lt;Func&lt;Sample, bool&gt;&gt;(Expression.AndAlso(condition.Body, additionalCondition.Body), condition.Parameters); 应该可以工作
  • 只是x.AnotherId == anotherId &amp;&amp; (!relationId&gt;0 || x.RelationId==relationId)吗?
  • @kienct89 我检查并添加了该扩展方法,但过滤器不起作用。
  • @RobertMcKee 效果很好。一个小小的改变 x.AnotherId == anotherId && (!(relationId>0) || x.RelationId==relationId)。但是为什么这种表达方法不起作用呢?

标签: c# linq


【解决方案1】:

这应该可以...

if(!(relationId>0))
{ 
  Expression<Func<Sample, bool>> condition = x => x.AnotherId == anotherId;
} else {
  Expression<Func<Sample, bool>> condition = x => x.AnotherId == anotherId && x.RelationId == relationId;
}

或者...

Expression<Func<Sample, bool>> condition = (!(relationId>0))
  ? x => x.AnotherId == anotherId
  : x => x.AnotherId == anotherId && x.RelationId == relationId;

虽然大多数时候我看到有人问如何做到这一点,这是因为他们真的在尝试这样做:

var query = something.Where(x=>x.AnotherId == anotherId);
if (relationId>0)
{
  query = query.Where(x=>x.RelationId == relationId);
}

【讨论】:

    【解决方案2】:

    正如其他人可能已经指出的那样,最简单的方法是

    x => x.AnotherId == anotherId && (relationId <= 0 || x.RelationId == relationId);
    

    但是如果你仍然想使用Expression,也许为了将来的证明,你需要定义parameterproperty

    另外,您需要将anotherId 转换为Nullable int

    例子:

    ParameterExpression param = Expression.Parameter(typeof(Sample), "x");
    var anotherIdParam = Expression.Property(param, "anotherId");
    var condition = Expression.Equal(anotherIdParam, Expression.Constant(anotherId));
    
    if (relationId > 0)
    {
        var relationIdParam = Expression.Property(param, "relationId");
        var additionalCondition = Expression.Equal(relationIdParam, Expression.Convert(Expression.Constant(relationId), typeof(Nullable<int>)));
        condition = Expression.AndAlso(condition, additionalCondition);
    }
    
    var finalExpression = Expression.Lambda<Func<Sample, bool>>(condition, param);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多