【问题标题】:Can I generate a linq expression dynamically in C#?我可以在 C# 中动态生成 linq 表达式吗?
【发布时间】:2012-05-08 11:34:14
【问题描述】:

我目前有一块看起来像这样的 Linq;

List<dynamic> childrenToBeRemoved = this.ItemsSource.Where(o => o.ParentID == "1234").ToList();

其中 ItemsSource 是动态的 ObservableCollection。

这很好用,但我遇到的问题是 ParentID 是一个可以变化的属性。例如。它可以命名为 ParentPkey 或 ParentKey 等。

我可以创建一个表达式来指定我想在比较中使用的属性吗?

我尝试过使用动态 linq,但它不能使用动态集合,但可以很好地与 pocos 集合一起使用。

谢谢...

【问题讨论】:

  • 为什么情况会有所不同? ...为什么不创建一个Func&lt;TItem, bool&gt;,然后将其注入为this.ItemSource.Where(myFunc),而不是使参数本身动态化(仍然可以,但表达式和泛型的开销可能不值得)?
  • yes, you can 但感觉就像是在使用动态霰弹枪杀死静态苍蝇。
  • 条件相同,但我在该表达式中使用的属性可能会改变,我正在使用表达式树构建器来构建条件,但您的正确似乎是一个巨大的锤子和一个很小的钉子。鉴于属性可以改变第一个 Func 方法的外观如何?
  • 为什么属性会变化?! (顺便说一句 - 如果属性不同,条件本身也不同!)
  • @Bendy 查看我的回答,了解如何使用Func&lt;TItem, bool&gt;-approach

标签: c# linq lambda


【解决方案1】:

查询是否为动态 linq 无关紧要

Expression<Func<Entity, int>> predicate = x => x.Id == myvalue;
from entity in _context.Entities.Where(predicate)
select entity;

查看 LinkKit 的 PredicateBuilder @http://www.albahari.com/nutshell/linqkit.aspx 那里也有足够的例子

将表达式转换为相应 sql 的责任在于 linq 提供程序,因此请确保您使用的提供程序支持相关方面

【讨论】:

    【解决方案2】:

    为什么要让实现本身动态化?您可以简单地进行动态调用!

    IEnumerable<MyItem> result;
    if (condition1)
    {
        result = this.Items.Where(arg => arg.ProductId == "123");
    }
    else if (condition2)
    {
        result = this.Items.Where(arg => arg.ProductPK == "123");
    }
    

    Func<Item, bool> predicate;
    if (condition1)
    {
        predicate = item => item.ProductId == "123";
    }
    else if (condition2)
    {
        predicate = item => item.ProductPK == "123";
    }
    var result = this.Items.Where(predicate);
    

    Sooo ...我相信你应该告诉我们更多关于你的实际问题 - 我认为目前没有任何需要实施某事 - 所以,我相信你的要求是不明确的!

    【讨论】:

      【解决方案3】:

      将你的linq表达式放入一个函数中,并将这个属性作为参数传入。

      【讨论】:

        【解决方案4】:

        如果你知道你的物品的类型,你可以使用反射:

        PropertyInfo parentProp = itemType.GetProperty("ParentKey or whatever");
        List<dynamic> childrenToBeRemoved = this.ItemsSource.Where(o => Equals("1234", parentProp.GetValue(o, null))).ToList();
        

        【讨论】:

        • 这种类型安全吗?如果属性不是 typeof System.String 怎么办?
        • 对,它甚至无法编译,我更正了 Equals 的更健壮使用
        • 你怎么能和null比较呢? :) ... 为什么不使用Equals()System.Object 上的静态实现)?在这种情况下,您将遇到的主要问题是,您必须将所有记录都保存到您的域中,因为这种比较无法转换为 EF 或类似...
        • 约定是Equals(null)返回false,string.Equals就是这种情况。所以没问题。
        • argl ... this.ItemsSource.Where(o =&gt; null.Equals(o.foo)) ... :) ... 你应该改用this.ItemsSource.Where(o =&gt; Equals(null, o.foo))
        猜你喜欢
        • 1970-01-01
        • 2015-11-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-08
        • 1970-01-01
        相关资源
        最近更新 更多