I have a situation where I have to dynamically build a linq query b开发者_如何学JAVAased on user selections. If I had to dynamically generate sql I could do it this way:
        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
       // )
Now I need to create a linq query the same way.
This works well with subsonic
var result = from p in db.products
             where p.productType1 == true || p.productType2 == true
             select p;
I tried it with PredicateBuilder http://www.albahari.com/nutshell/predicatebuilder.aspx but that throws an exception with subsonic.
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);
the exception that is thrown: NotSupportedException: The member 'productType1' is not supported
at SubSonic.DataProviders.MySQL.MySqlFormatter.VisitMemberAccess.
Anybody has an idea how to get this query to work:
Maybe Dynamic LINQ will be helpful?
Here is an usage example, as requested by geocine. It requires Dynamic 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 };
it looks akward but it works.
 
         
                                         
                                         
                                         
                                        ![Interactive visualization of a graph in python [closed]](https://www.devze.com/res/2023/04-10/09/92d32fe8c0d22fb96bd6f6e8b7d1f457.gif) 
                                         
                                         
                                         
                                         加载中,请稍侯......
 加载中,请稍侯......
      
精彩评论