2013-06-02 2 views
3

Disons que j'ai deux entités:Linq Expression pour faire correspondre un complexe beaucoup-à-plusieurs

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

(Nous considérerons les animaux comme étant capable de manger quoi que ce soit qui ne contient pas tout ce qu'ils » Je ne suis pas capable de manger.) Maintenant, étant donné un aliment particulier, je voudrais savoir à quels animaux je peux le nourrir, et donné un animal particulier, j'aimerais savoir ce que je peux le nourrir.

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

L'expression inverse ressemble étrangement:

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

Alors qu'est-ce que vraiment logique est une expression combinée:

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

Et en quelque sorte les deux méthodes ci-dessus, GetAllowedFoods et GetAllowedAnimals devrait invoquer l'expression IsAllowedDiet.

Je suppose que c'est quelque chose que LinqKit devrait pouvoir faire en un clin d'oeil, mais en tant que débutant de rang avec LinqKit, je n'ai aucune idée de la syntaxe correcte!

+0

Qu'en est-il de faire de IsAllowedDiet une méthode simple, qui prend l'animal et la nourriture comme paramètres, et renvoie un booléen. – aquaraga

+0

@aquaraga - ça doit être traduisible en SQL. D'où la nécessité d'une «expression» plutôt que d'un simple «Func». –

Répondre

0

Je l'ai élaboré. La méthode IsAllowedDiet() reste telle qu'exprimée dans la question. GetAllowedFoods() et GetAllowedAnimals() sont exprimés comme suit:

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

Je commence à profiter LinqKit! :-)

Questions connexes