【问题标题】:Combine property selector expression tree and value to create a predicate for EF filtering - create filter from lambda selector and value结合属性选择器表达式树和值来创建用于 EF 过滤的谓词 - 从 lambda 选择器和值创建过滤器
【发布时间】:2015-05-14 14:13:59
【问题描述】:

给定一个具有任意属性的简单类(为了讨论,可以说 Id、Name 和 Description)

给定该类的一个实例,我想通过指定要匹配的属性在数据库中找到匹配的条目

我正在尝试在这方面做一些类似于 EF 的 AddOrUpdate 方法的事情,但我需要将实体返回给我以进行进一步处理。

var match = new SomeClass{Name="Whatever"};
var found = Context.SomeClass.Find(x=>x.Name, match);

public static T Find<T>(this DbSet<T> set, Expression<Func<T, object>> matchOn, T matchAgainst) where T : class {
  var func = matchOn.Compile();
  var valueToFind = func(matchAgainst);


 var combinedExpression = //matchon + "=" + valueToFind;
 var found = set.FirstOrDefault(combinedExpression);
 return found;
 }

这给了我传入对象中属性的值,但我现在需要将该值与传入的表达式结合起来,并将其传递给数据库集。

IE,我有效尝试运行的代码是 set.FirstOrDefault(x=&gt;x.Name==valueToFind) 我如何获取 matchon 表达式(包含 x=&gt;x.Name)并将其与 ==valueToFind 结合以从他们那里获取 x=&gt;x.Name==valueToFind ?

如何构建组合表达式? (我意识到上面的“字符串”代码是完全错误的,但我试图了解我需要该函数做什么,但我不知道该语法会是什么样子。)

对于手动编码的示例,只需传入带有值集的硬编码 lambda 就很容易了,但我的用例涉及运行对象集合并为每个对象找到匹配项,因此值不会是直到运行时才知道,并且该方法必须适用于任意类型和各种属性,因此我也无法对属性名称进行硬编码。

【问题讨论】:

    标签: c# linq entity-framework lambda expression-trees


    【解决方案1】:

    如果你有一个属性选择器和一个要比较的值,你可以得到一个这样的表达式树:

    public static Func<TEntity, bool> GetComparer<TEntity,TProperty>(
        Expression<Func<TEntity,TProperty>> selector, TProperty value)
    {
        var propertyRef = selector.Body;
        var parameter = selector.Parameters[0];
        var constantRef = Expression.Constant(value);
        var comparer 
            = Expression.Lambda<Func<TEntity, bool>>
                (Expression.Equal(propertyRef, constantRef), parameter)
                .Compile();
        return comparer;
    }
    

    示例用法:

    var comparer = GetComparer<Person, string>(p => p.Name, "John");
    var persons = Person.GetPersons();
    var john = persons.FirstOrDefault(comparer);
    

    【讨论】:

    • 我已经传入了 x=>x.propertyName 类型的 lambda,我需要获取该 lambda,并将其与已知值结合以生成 x=>x.propertyname==knownValue
    • 也许您可以通过明确指出这是您的问题来改进您的问题。有太多的文字,我误解了它。不怪你,只是建议如何帮助人们一开始就搞定它。我会看看我是否能找到如何操作表达式树。
    • @JasonCoyne 我已经更新了我的答案。我为您提供了一个静态方法,可以满足您的需求
    • 比较器系列是我所需要的魔法,我相信。立即测试。
    • 请注意,如果您将属性选择器类型保留为“object”,并将值保留为“T”,则很可能无法正常工作。他们应该匹配。我在我的静态方法中说清楚了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多