2009-09-17 8 views
0

Je suis confronté à un scénario où je dois filtrer un seul objet basé sur de nombreux objets. Par exemple, j'ai un objet Grocery qui comprend à la fois des propriétés de fruits et de légumes. Puis j'ai l'individu Fruits et Objets végétaux.Une seule expression de requête LINQ peut-elle être encadrée dans ce scénario?

Mon objectif est le suivant:

var groceryList = from grocery in Grocery.ToList() 
        from fruit in Fruit.ToList() 
        from veggie in Vegetable.ToList() 
        where (grocery.fruitId = fruit.fruitId) 
        where (grocery.vegId = veggie.vegId) 
        select (grocery); 

Le problème que je suis confronté est lorsque les fruits et légumes objets sont vides. Par vide, je veux dire que leur nombre de liste est 0 et je veux appliquer le filtre seulement si la liste de filtre est remplie.

Je suis également pas en mesure d'utiliser quelque chose comme puisque les objets sont nuls:

var groceryList = from grocery in Grocery.ToList() 
        from fruit in Fruit.ToList() 
        from veggie in Vegetable.ToList() 
        where (grocery.fruitId = fruit.fruitId || fruit.fruitId == String.Empty) 
        where (grocery.vegId = veggie.vegId || veggie.vegId == String.Empty) 
        select (grocery); 

, je compte donc pour vérifier fruits et nombre de légumes liste ... et les filtrer comme séparer les expressions sur successivement filtré Épicerie objets.

Mais existe-t-il un moyen de toujours obtenir la liste dans le cas d'objets NULL dans une seule expression de requête?

+2

Êtes-vous juste essayer faire une jointure avec Linq? Désolé, je ne comprends pas complètement la question. –

+0

Exactement, juste une jointure. Mais quelle est la meilleure approche à adopter lorsque l'un des objets filtre est nul? –

+0

C'est pourquoi c'est une bonne idée d'interdire les collections nulles. Tout le code que j'écris impose que les nulls ne soient jamais utilisés, en faveur des collections vides. – bobbymcr

Répondre

0

Essayez quelque chose comme ce qui suit:

var joined = grocery.Join(fruit, g => g.fruitId, 
           f => f.fruitId, 
           (g, f) => new Grocery() { /*set grocery properties*/ }). 
       Join(veggie, g => g.vegId, 
          v => v.vegId, 
          (g, v) => new Grocery() { /*set grocery properties*/ }); 

Où je l'ai dit propriétés d'épicerie de jeu vous pouvez définir les propriétés de l'objet d'épicerie du g, f, v variables du sélecteur. D'intérêt sera évidemment g.fruitId = f.fruitId et g.vegeId = v.vegeId.

0
IEnumerable<Grocery> query = Grocery 

if (Fruit != null) 
{ 
    query = query.Where(grocery => 
    Fruit.Any(fruit => fruit.FruitId == grocery.FruitId)); 
} 

if (Vegetable != null) 
{ 
    query = query.Where(grocery => 
    Vegetable.Any(veggie => veggie.VegetableId == grocery.VegetableId)); 
} 

List<Grocery> results = query.ToList(); 
0
var groceryList = 
    from grocery in Grocery.ToList() 
    join fruit in Fruit.ToList() 
     on grocery.fruidId equals fruit.fruitId 
     into groceryFruits 
    join veggie in Vegetable.ToList() 
     on grocery.vegId equals veggie.vegId 
     into groceryVeggies 
    where ... // filter as needed 
    select new 
    { 
    Grocery = grocery, 
    GroceryFruits = groceryFruits, 
    GroceryVeggies = groceryVeggies 
    }; 
0

Vous devez utiliser leftouter rejoindre (comme TSQL) pour cela. en dessous de la requête pour le tour

private void test() 
{ 
    var grocery = new List<groceryy>() { new groceryy { fruitId = 1, vegid = 1, name = "s" }, new groceryy { fruitId = 2, vegid = 2, name = "a" }, new groceryy { fruitId = 3, vegid = 3, name = "h" } }; 
    var fruit = new List<fruitt>() { new fruitt { fruitId = 1, fname = "s" }, new fruitt { fruitId = 2, fname = "a" } }; 
    var veggie = new List<veggiee>() { new veggiee { vegid = 1, vname = "s" }, new veggiee { vegid = 2, vname = "a" } }; 
    //var fruit= new List<fruitt>(); 
    //var veggie = new List<veggiee>(); 

    var result = from g in grocery 
       join f in fruit on g.fruitId equals f.fruitId into tempFruit 
       join v in veggie on g.vegid equals v.vegid into tempVegg 
       from joinedFruit in tempFruit.DefaultIfEmpty() 
       from joinedVegg in tempVegg.DefaultIfEmpty() 
       select new { g.fruitId, g.vegid, fname = ((joinedFruit == null) ? string.Empty : joinedFruit.fname), vname = ((joinedVegg == null) ? string.Empty : joinedVegg.vname) }; 

    foreach (var outt in result) 
     Console.WriteLine(outt.fruitId + " " + outt.vegid + " " + outt.fname + " " + outt.vname); 
} 
public class groceryy 
{ 
    public int fruitId; 
    public int vegid; 
    public string name; 
} 
public class fruitt 
{ 
    public int fruitId; 
    public string fname; 
} 
public class veggiee 
{ 
    public int vegid; 
    public string vname; 
} 

EDIT: ceci est le résultat de l'échantillon

1 1 ss

2 2 aa

Questions connexes