SubSonic 3,在运行时构建动态或表达

发布于 2024-09-30 05:27:10 字数 2274 浏览 3 评论 0原文

我遇到的情况是,我必须根据用户选择动态构建 linq 查询。 如果我必须动态生成 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
       // )

现在我需要以相同的方式创建一个 linq 查询。

这适用于亚音速

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

我尝试使用 PredicateBuilder 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:不支持成员“productType1” 位于 SubSonic.DataProviders.MySQL.MySqlFormatter.VisitMemberAccess。

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

I have a situation where I have to dynamically build a linq query based 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:

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

Saygoodbye 2024-10-07 05:27:10

也许 动态LINQ会有帮助吗?

Maybe Dynamic LINQ will be helpful?

木緿 2024-10-07 05:27:10

这是一个使用示例,根据 geocine 的要求。
它需要动态 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 };

它看起来很尴尬,但很有效。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文