c# - Linq:如何对关联对象使用规范

标签 c# linq expression-trees specification-pattern

我正在使用这种形式的规范:

public static Expression<Func<User, bool>> IsSuperhero
{
  get
  {
    return x => x.CanFly && x.CanShootLasersFromEyes;
  }
}

现在我可以在表单中使用此规范:

var superHeroes = workspace.GetDataSource<User>().Where(UserSpecifications.IsSuperhero);

但我不确定如何针对这样的关联对象使用规范:

var loginsBySuperheroes = workspace.GetDataSource<Login>().Where(x => x.User [ ??? ]);

有没有办法做到这一点,或者我是否需要重新考虑我的规范实现?

最佳答案

本质上,您需要创建一个 Expression<Func<Login, bool>>从登录中收集关联的用户,然后应用现有的 IsSuperhero以该用户为准。完成此操作的规范方法是使用 Expression.Invoke在“包含”表达式(本例中为 IsSuperHero)上,将其参数替换为适当的参数。

不幸的是,这种方法用手做起来很麻烦。更糟糕的是,许多 LINQ 提供程序(例如 LINQ to Entities)根本不喜欢这种“表达式中的表达式”方法。解决这个问题的方法是将“调用的”表达式“内联”到更大的表达式中,这样它看起来就像一个单个、巨大的表达式树。

幸运的是,这里有方便的图书馆 LINQKit可以帮助解决这个问题:

#region LINQKit Magic

Expression<Func<Login, bool>> predicate = login => IsSuperHero.Invoke(login.User);
var expandedPredicate = predicate.Expand(); 

#endregion LINQKit Magic

var loginsBySuperheroes = workspace.GetDataSource<Login>().Where(expandedPredicate);

关于c# - Linq:如何对关联对象使用规范,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8049901/

相关文章:

c# - LINQ: "Types in Union or Concat are constructed incompatibly."

c# - 访问对象属性而不转换为类型

c# - 如何将 where 语句发送到在 LINQ 语句中动态执行的方法?

c# - 有没有办法在表达式树中设置 'DeclaringType'?

c# - 更改线程优先级 - Unity 3d

c# - 使用 csvHelper 处理 csv 文件中的无效条目

c# - 对象存储在 session 中,但在检索时它为空

c# - Entity Framework 4.1 通过设置外键映射关系

c# - 如何在不丢失强类型的情况下返回代码优先 Entity Framework 中的 DbGeography.Distance 计算值?

c# - Func<string, bool> 到 bool 用于表达式树