Выражение Linq для сопоставления сложного отношения "многие ко многим"

Допустим, у меня есть две сущности:

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));
}

И как-то два метода выше, GetAllowedFoods а также GetAllowedAnimals должен вызвать выражение IsAllowedDiet,

Я предполагаю, что это то, что LinqKit должен уметь делать в одно мгновение, но как новичок в LinqKit, я понятия не имею, какой будет правильный синтаксис!

1 ответ

Решение

Я решил это. Метод 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!:-)

Другие вопросы по тегам