代码之家  ›  专栏  ›  技术社区  ›  Mike

我如何表达不使用lambdas?

  •  7
  • Mike  · 技术社区  · 15 年前

    not in 使用NHLambdaExtensions的NHibernate标准API的子句。通过阅读文档,我能够实现 in

    .Add(SqlExpression.In<Zone>(z => zoneAlias.ZoneId, new int[] { 1008, 1010 }))
    

    然而,当我把它包起来 SqlExpression.Not

    Error   5   The best overloaded method match for 'NHibernate.LambdaExtensions.SqlExpression.Not<oms_dal.Models.Zone>(System.Linq.Expressions.Expression<System.Func<oms_dal.Models.Zone,bool>>)' has some invalid arguments
    Error   6   Argument '1': cannot convert from 'NHibernate.Criterion.ICriterion' to 'System.Linq.Expressions.Expression<System.Func<oms_dal.Models.Zone,bool>>'
    

    .Add(SqlExpression.Not<Zone>(SqlExpression.In<Zone>(x => zoneAlias.ZoneId, new int[] { 1008, 1010 })))
    

    我怎样才能做到这一点?使用常规的criteriaapi,我可以做到这一点

    .Add(Restrictions.Not(Restrictions.In("z.ZoneId", new[] { 1008, 1010 })))
    
    2 回复  |  直到 15 年前
        1
  •  1
  •   KeithS    15 年前

    我没有直接使用criteria(我通常使用Linq2NH),但它看起来不仅仅需要一个布尔lambda,所以不能给它另一个条件。虽然我看到NH在lambdas中的数组成员有问题,但这可能是可行的:

    .Add(SqlExpression.Not<Zone>(z=>new[]{1008,1010}.Contains(z.ZoneId))
    

    编辑:废话。这里的情况是,框架实际上并没有使用lambda,因此在编译时,框架在运行查询的过程中从来没有实际调用过lambda。相反,它反省地检查委托的MSIL,反向工程lambda表达式,并将其转换为SQL命令的字符串。很明显,这是一个相当复杂的过程,设计者试图通过让您指定关于您正在做什么的提示(在本例中是您声明的SqlExpression类型)并寻找模式来标识该过程来简化该过程。不过,在本例中,即使给出了提示,框架也不知道您要做什么。

    如果求值Not()子句背后的转换器无法预知逻辑循环或方法调用的目的,那么您很可能会被

    .Add(SqlExpression.Not<Zone>(z=>z.ZoneId == 1008
                                    || z.ZoneId == 1010))
    

    天知道,为了让Linq2NHibernate正常工作,我不得不用这种方式来简化表达式。

        2
  •  2
  •   Stu    15 年前

    将旧世界与lambdas结合使用似乎是可行的:

    .Add(Expression.Not(SqlExpression.In<Zone>(z => zoneAlias.ZoneId, new int[] { 1008, 1010 }));