Linq Expression用于匹配复杂的多对多关系

时间:2013-06-02 12:12:22

标签: c# linq expression-trees linqkit

假设我有两个实体:

public class Animal {
  public int ID { get; set; }
  public string Name { get; set; }
  public bool EatsVegetables { get; set; }
  public bool EatsMeat { get; get; }
  public bool EatsFruits { get; set; }
}

public bool Food {
  public int ID { get; set; }
  public string Name { get; set; }
  public bool ContainsVegetables { get; set; }
  public bool ContainsMeat { get; get; }
  public bool ContainsFruits { get; set; }
}

(我们会认为这些动物可以吃任何不含任何东西的东西。)现在给出一种特殊的食物,我想知道哪些动物可以喂它为了给一只特定的动物,我想找出能喂它的东西。

public static Expression<Func<Animal, IEnumerable<Food>>> GetAllowedFoods(MyDataContext db) {
  return a => db.Foods.Where(f => 
    (a.EatsVegetables || !f.ContainsVegetables)
    && (a.EatsMeat || !f.ContainsMeat)
    && (a.EatsFruits || !f.ContainsFruits));
}

相反的表达看起来非常相似:

public static Expression<Func<Food, IEnumerable<Animal>>> GetAllowedAnimals(MyDataContext db) {
  return f => db.Animals.Where(a => 
    (a.EatsVegetables || !f.ContainsVegetables)
    && (a.EatsMeat || !f.ContainsMeat)
    && (a.EatsFruits || !f.ContainsFruits));
}

所以真正有意义的是组合表达式:

public static Expression<Func<Animal, Food, bool>> IsAllowedDiet() {
  return (a, f) => 
    (a.EatsVegetables || !f.ContainsVegetables)
    && (a.EatsMeat || !f.ContainsMeat)
    && (a.EatsFruits || !f.ContainsFruits));
}

以上两种方法GetAllowedFoodsGetAllowedAnimals应该以某种方式调用表达式IsAllowedDiet

我认为这是LinqKit应该能够快速完成的事情,但作为LinqKit的排名初学者,我不知道正确的语法是什么!

1 个答案:

答案 0 :(得分:0)

我解决了这个问题。方法IsAllowedDiet()仍然在问题中表达。 GetAllowedFoods()GetAllowedAnimals()表示如下:

public static Expression<Func<Animal, IEnumerable<Food>>> GetAllowedFoods(MyDataContext db) {
  var isAllowed = IsAllowedDiet();
  return a => db.Foods.AsExpandable().Where(f => isAllowed.Invoke(a, f));
}

public static Expression<Func<Food, IEnumerable<Animal>>> GetAllowedAnimals(MyDataContext db) {
  var isAllowed = IsAllowedDiet();
  return f => db.Animals.AsExpandable().Where(a => isAllowed.Invoke(a, f));
}

我开始喜欢LinqKit了! : - )