代码之家  ›  专栏  ›  技术社区  ›  Clarence Klopfstein

linq to对象中的动态where子句

  •  0
  • Clarence Klopfstein  · 技术社区  · 14 年前

    我知道网络上有很多这样的例子,但我似乎不能让它发挥作用。

    让我尝试设置它,我有一个自定义对象列表,我需要限制一系列值。

    我有一个排序变量,它根据用户界面上的某些操作进行更改,我需要基于此对对象进行不同的处理。

    这是我的目标:

    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")
    
    3 回复  |  直到 9 年前
        1
  •  2
  •   Aaronaught    14 年前

    也许不能直接回答你的问题,但这里不需要动态查询。您可以将此查询编写为:

    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结合在一起;它实际上对动态生成条件没有太大帮助。

        2
  •  1
  •   Kris Krause    14 年前
    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);
    
        3
  •  1
  •   Stan R.    14 年前

    阅读这篇由Scottgu撰写的关于dlinq的伟大文章

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

    你需要这样的东西

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

    如果你下载了样本,你需要找到 Dynamic.cs 在样本中归档。您需要将此文件复制到项目中,然后添加 using System.Linq.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<Foo> 很容易。

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