Question

J'ai une situation où je dois construire dynamiquement une requête LINQ en fonction des choix de l'utilisateur. Si je devais générer dynamiquement sql je pouvais le faire de cette façon:

        var sb = new StringBuilder();
        sb.AppendLine("SELECT * FROM products p");
        sb.AppendLine("WHERE p.CategoryId > 5");

        // these variables are not static but choosen by the user
        var type1 = true;
        var type2 = true;
        var type3 = false;

        string type1expression = null;
        string type2expression = null;
        string type3expression = null;

        if (type1)
            type1expression = "p.productType1 = true";

        if (type2)
            type2expression = "p.productType2 = true";

        if (type3)
            type3expression = "p.productType3 = true";

        string orexpression = String.Empty;
        foreach(var expression in new List<string>
               {type1expression, type2expression, type3expression})
        {
            if (!String.IsNullOrEmpty(orexpression) &&
                    !String.IsNullOrEmpty(expression))
                orexpression += " OR ";

            orexpression += expression;
        }

        if (!String.IsNullOrEmpty(orexpression))
        {
            sb.AppendLine("AND (");
            sb.AppendLine(orexpression);
            sb.AppendLine(")");
        }

        // result:

       // SELECT * FROM products p
       // WHERE p.CategoryId > 5
       // AND (
       // p.productType1 = true OR p.productType2 = true
       // )

Maintenant, je dois créer une requête LINQ de la même manière.

Cela fonctionne bien avec subsonique

var result = from p in db.products
             where p.productType1 == true || p.productType2 == true
             select p;

Je l'ai essayé avec PredicateBuilder http://www.albahari.com/nutshell/predicatebuilder.aspx mais qui génère une exception avec subsonique.

var query = from p in db.products
            select p;

var inner = PredicateBuilder.False<product>();
inner = inner.Or(p => p.productType1 == true);
inner = inner.Or(p => p.productType2 == true);

var result = query.Where(inner);

l'exception qui est levée: NotSupportedException: The member 'productType1' is not supported à SubSonic.DataProviders.MySQL.MySqlFormatter.VisitMemberAccess.

Tout le monde a une idée comment obtenir cette requête au travail:

Était-ce utile?

La solution

Peut-être Dynamic LINQ sera utile?

Autres conseils

Voici un exemple d'utilisation, tel que demandé par geocine. Elle exige dynamique LINQ.

        var productTypes = new int[] {1,2,3,4};
        var query = from p in db.products
                    select p;

        if (productTypes.Contains(1))
            query.Add("productType1 = @0");

        if (productTypes.Contains(2))
            query.Add("productType2 = @0");

        if (productTypes.Contains(3))
            query.Add("productType3 = @0");

        if (productTypes.Contains(4))
            query.Add("productType4 = @0");

        if (productTypes.Count > 0)
        {
            string result = String.Join(" OR ", productTypes);
            query = query.Where("(" + result + ")", true);
        }

        var result = from p in query
                     select new {Id = p.ProductId, Name = p.ProductName };

il semble akward mais cela fonctionne.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top