代码之家  ›  专栏  ›  技术社区  ›  Jürgen Steinblock

亚音速3,在运行时生成动态或表达式

  •  2
  • Jürgen Steinblock  · 技术社区  · 13 年前

    如果我必须动态生成sql,我可以这样做:

            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
           // )
    

    这很适合亚音速

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

    http://www.albahari.com/nutshell/predicatebuilder.aspx 但亚音速也有例外。

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

    NotSupportedException: The member 'productType1' is not supported SubSonic.DataProviders.MySQL.MySqlFormatter.VisitMemberAccess

    任何人都知道如何让这个查询工作:

    2 回复  |  直到 13 年前
        1
  •  1
  •   Devart    13 年前

    也许 吧 Dynamic LINQ 会有帮助吗?

        2
  •  0
  •   Jürgen Steinblock    13 年前

    它需要动态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 };
    

    它看起来很好,但很管用。