web-dev-qa-db-fra.com

Instancier IQueryable vide pour une utilisation avec Linq vers sql

Je dois être en mesure d'avoir un paramètre facultatif dans une requête Linq, ou être en mesure d'affecter la requête à un var dans quelque chose comme un IF si ce paramètre facultatif doit être supprimé de la requête.

Si je définis la requête var à l'intérieur de l'instruction IF, elle m'indique que la var n'existe pas dans le contexte lorsque j'essaie de la parcourir.

if (whichGroup == "All")
        {
            var listOppLineData = (from o in db.opportunity_vws
                                   where o.fiscal_yr_and_qtr == qtr
                                   select o
                                  );
        }
        else
        {
            var listOppLineData = (from o in db.opportunity_vws
                                   where o.fiscal_yr_and_qtr == qtr && o.Group == whichGroup
                                   select o
                                  );
        }

        foreach (var data in listOppLineData)  //listOppLineData doesn't exist here
        {

Je dois définir la var avant l'instruction IF, je pense, mais je ne sais pas à quoi la définir.

var listOppLineData = ""; // gives me 
Cannot implicitly convert type 'System.Linq.IQueryable<Forecast.Models.opportunity_vw>' to 'string'

IQueryable listOppLineData = new IQueryable(); //gives me
        Cannot create an instance of the abstract class or interface 'System.Linq.IQueryable'
44
user2073077

Essaye ça:

IQueryable<opportunity_vw> listOppLineData;

Ceci définit la variable, mais vous attendez de l'initialiser.

De plus, en regardant votre requête, vous pouvez tout faire en un, comme ceci:

var listOppLineData = (from o in db.opportunity_vws
                      where o.fiscal_yr_and_qtr == qtr && (o.Group == whichGroup || whichGroup == "All")
                      select o
                      );
19
Simon C

Essaye ça. Vous pouvez créer un type générique avec T ou un type spécifique en remplaçant T par votre nom de type.

IQueryable listOppLineData = Enumerable.Empty<T>().AsQueryable()
124
Krishna

Votre problème est que lorsque vous déclarez une variable en C #, vous la déclarez uniquement dans la portée actuelle. Donc, si vous déclarez la variable listOppLineData dans le bloc if, vous ne pouvez l'utiliser que dans ce bloc, mais pas ailleurs. (Vous pouvez définir une autre variable avec le même nom dans un autre bloc, mais ce serait une variable complètement différente, donc elle n'aurait pas la valeur que vous avez assignée à la première variable.)

Comme vous l'avez déjà compris, vous devez déclarer la variable en dehors des blocs if.

Votre première tentative n'a pas fonctionné, car le compilateur a vu que vous n'aviez pas spécifié explicitement le type de la variable (c'est ce que fait var) et vous avez affecté un string à la variable. Il a donc déduit que le type de la variable est string. Et vous ne pouvez pas affecter quelque chose qui n'est pas un string à une telle variable.

Votre deuxième tentative n'a pas fonctionné, car vous ne pouvez pas créer d'instance d'interface. (Si vous souhaitez créer une instance, il doit s'agir d'un type spécifique, généralement une classe.) Et même si vous avez corrigé cela, le IQueryable non générique ne connaît pas le type des éléments qu'il contient, donc le foreach ne fonctionnerait pas bien.

Mais vous n'avez pas besoin d'attribuer de valeur à la variable, car elle est affectée dans les deux branches de if. Et le bon type ici est le générique IQueryable<T>, avec T étant opportunity_vw. Cela signifie que le bon code est:

IQueryable<opportunity_vw> listOppLineData;

if (whichGroup == "All")
{
    listOppLineData = …;
}
else
{
    listOppLineData = …;
}

foreach (var data in listOppLineData)
{
    …
}

Si vous vouliez vraiment attribuer une valeur à la variable (bien qu'il n'y ait aucune raison de le faire ici), vous pouvez utiliser null (qui ne représente aucune valeur):

IQueryable<opportunity_vw> listOppLineData = null;
5
svick

Ça marche pour moi:

IQueryable<string> _labTests = Enumerable.Empty<string>().AsQueryable();
2
agileDev

Essayez d'ajouter .ToList ();

var listOppLineData = (from o in db.opportunity_vws
                                   where o.fiscal_yr_and_qtr == qtr
                                   select o
                                  ).ToList();

Mise à jour

Et corrigez la requête.

Vous n'aurez rien à répéter sans le .ToList ();

Mise à jour Head Out of Butt

var listOppLineData = (from o in db.opportunity_vws
                      where (whichGroup == "All" || o.Group == whichGroup)
                      && (o.fiscal_yr_and_qtr == qtr)
                      select o);

Mettez votre "court" avant le bloc opératoire, afin que la deuxième partie ne soit jamais évaluée si elle n'est pas nécessaire. J'utiliserais quand même le .ToList ().

0
Trey Gramann