LINQ to Objects 中的动态 where 子句

发布于 2024-08-16 21:43:37 字数 1077 浏览 5 评论 0原文

我知道网上有很多这方面的例子,但我似乎无法让它发挥作用。

让我尝试进行设置,我有一个自定义对象列表,我需要将其限制在一系列值上。

我有一个排序变量,它会根据 UI 上的某些操作而变化,并且我需要根据该变量以不同的方式处理对象。

这是我的目标:

MyObject.ID - Just an identifier
MyObject.Cost - The cost of the object.
MyObject.Name - The name of the object.

现在我需要根据成本范围来过滤它,所以考虑到我可能会受到底部两个属性之一的限制,所以我将有类似的东西。

var product = from mo in myobject 
              where mo.Cost <= 10000

或者

var product = from mo in myobject
              where mo.Name equals strName

现在我的项目中有动态 linq,但我不知道如何让它实际工作,因为当我做一些我只得到的示例时:

Func<Tsourse>bool> predicate

作为一个选项。

更新: 我正在尝试找到一种解决方案来帮助我具体化我的代码,因为现在我的 linq 查询需要进行大量复制和粘贴。

更新2:
之间是否存在明显的性能差异

var product = from mo in myobject 
... a few joins ...
where mo.Cost <= 10000


var product = (from mo in myobject 
... a few joins ...)
.AsQueryable()
.Where("Cost > 1000")

I know there are a lot of examples of this on the web, but I can't seem to get this to work.

Let me try to set this up, I have a list of custom objects that I need to have limited on a range of values.

I have a sort variable that changes based on some action on the UI, and I need to process the object differently based on that.

Here is my object:

MyObject.ID - Just an identifier
MyObject.Cost - The cost of the object.
MyObject.Name - The name of the object.

Now I need to filter this based on a range in the cost, so I will have something similar to this, considering that I could be limiting by Either of my bottom two properties.

var product = from mo in myobject 
              where mo.Cost <= 10000

or

var product = from mo in myobject
              where mo.Name equals strName

Now I have the dynamic linq in my project, but I'm not figuring out how to get it to actually work, as when I do some of the examples I am only getting:

Func<Tsourse>bool> predicate

as an option.

Update:
I am trying to find a solution that helps me Objectify my code, as right now it is a lot of copy and paste for my linq queries.

Update 2:
Is there an obvious performance difference between:

var product = from mo in myobject 
... a few joins ...
where mo.Cost <= 10000

and

var product = (from mo in myobject 
... a few joins ...)
.AsQueryable()
.Where("Cost > 1000")

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

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

发布评论

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

评论(3

攒眉千度 2024-08-23 21:43:37

也许没有直接回答你的问题,但 DynamicQuery 这里是不必要的。您可以将此查询编写为:

public IEnumerable<MyObject> GetMyObjects(int? maxCost, string name)
{
    var query = context.MyObjects;
    if (maxCost != null)
    {
        query = query.Where(mo => mo.Cost <= (int)maxCost);
    }
    if (!string.IsNullOrEmpty(name))
    {
        query = query.Where(mo => mo.Name == name);
    }
    return query;
}

如果条件互斥,则只需将第二个 if 更改为 else if 即可。

我一直使用这种模式。 “动态查询”的真正含义是纯SQL与Linq的结合;它对于动态生成条件并没有多大帮助。

Maybe not directly answering your question, but DynamicQuery is unnecessary here. You can write this query as:

public IEnumerable<MyObject> GetMyObjects(int? maxCost, string name)
{
    var query = context.MyObjects;
    if (maxCost != null)
    {
        query = query.Where(mo => mo.Cost <= (int)maxCost);
    }
    if (!string.IsNullOrEmpty(name))
    {
        query = query.Where(mo => mo.Name == name);
    }
    return query;
}

If the conditions are mutually exclusive then just change the second if into an else if.

I use this pattern all the time. What "Dynamic Query" really means is combining pure SQL with Linq; it doesn't really help you that much with generating conditions on the fly.

夢归不見 2024-08-23 21:43:37
using System.Linq;

var products = mo.Where(x => x.Name == "xyz");

var products = mo.Where(x => x.Cost <= 1000);

var products = mo.Where(x => x.Name == "xyz" || x.Cost <= 1000);
using System.Linq;

var products = mo.Where(x => x.Name == "xyz");

var products = mo.Where(x => x.Cost <= 1000);

var products = mo.Where(x => x.Name == "xyz" || x.Cost <= 1000);
暮倦 2024-08-23 21:43:37

阅读 ScottGu 撰写的关于 DLINQ 的这篇精彩文章

动态 LINQ(第 1 部分:使用 LINQ 动态查询库)

您将需要类似的内容

var product = myobject.Where("Cost <= 10000");
var product = myobject.Where("Name = @0", strName);

如果您下载了示例,则需要找到 Dynamic.cs示例中的 文件。您需要将此文件复制到您的项目中,然后添加
using System.Linq.Dynamic; 到您尝试在其中使用 Dynamic Linq 的类。

编辑:回答您的编辑。是的,当然存在性能差异。如果您事先知道过滤器的变化,那么我建议您不使用 DLINQ 将它们写出来。

您可以像这样创建自己的扩展方法。

 public static class FilterExtensions
    {
        public static IEnumerable<T> AddFilter<T,T1>(this IEnumerable<T> list, Func<T,T1, bool> filter,  T1 argument )
        {
            return list.Where(foo => filter(foo, argument) );
        }
    }

然后创建您的过滤器方法。

        public bool FilterById(Foo obj, int id)
        {
            return obj.id == id;
        }

        public bool FilterByName(Foo obj, string name)
        {
            return obj.name == name;
        }

现在您可以非常轻松地在 IEnumerable 上使用它。

    List<Foo> foos = new List<Foo>();
    foos.Add(new Foo() { id = 1, name = "test" });
    foos.Add(new Foo() { id = 1, name = "test1" });
    foos.Add(new Foo() { id = 2, name = "test2" });

    //Example 1
    //get all Foos's by Id == 1
    var list1 = foos.AddFilter(FilterById, 1);

    //Example 2
    //get all Foo's by name ==  "test1"
    var list2 = foos.AddFilter(FilterByName, "test1");

    //Example 3
   //get all Foo's by Id and Name
   var list1 = foos.AddFilter(FilterById, 1).AddFilter(FilterByName, "test1");

Read this great post on DLINQ by ScottGu

Dynamic LINQ (Part 1: Using the LINQ Dynamic Query Library)

You would need something like

var product = myobject.Where("Cost <= 10000");
var product = myobject.Where("Name = @0", strName);

If you downloaded the samples you need to find the Dynamic.cs file in the sample. You need to copy this file into your project and then add
using System.Linq.Dynamic; to the class you are trying to use Dynamic Linq in.

EDIT: To answer your edit. Yes, there is of course a performance difference. If you know the variations of filters beforehand then I would suggest writing them out without using DLINQ.

You can create your own Extension Method like so.

 public static class FilterExtensions
    {
        public static IEnumerable<T> AddFilter<T,T1>(this IEnumerable<T> list, Func<T,T1, bool> filter,  T1 argument )
        {
            return list.Where(foo => filter(foo, argument) );
        }
    }

Then create your filter methods.

        public bool FilterById(Foo obj, int id)
        {
            return obj.id == id;
        }

        public bool FilterByName(Foo obj, string name)
        {
            return obj.name == name;
        }

Now you can use this on an IEnumerable<Foo> very easily.

    List<Foo> foos = new List<Foo>();
    foos.Add(new Foo() { id = 1, name = "test" });
    foos.Add(new Foo() { id = 1, name = "test1" });
    foos.Add(new Foo() { id = 2, name = "test2" });

    //Example 1
    //get all Foos's by Id == 1
    var list1 = foos.AddFilter(FilterById, 1);

    //Example 2
    //get all Foo's by name ==  "test1"
    var list2 = foos.AddFilter(FilterByName, "test1");

    //Example 3
   //get all Foo's by Id and Name
   var list1 = foos.AddFilter(FilterById, 1).AddFilter(FilterByName, "test1");
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文