Jas*_*yne 3 c# linq lambda entity-framework expression-trees
给定一个具有任意属性的简单类(讨论可以说是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;
}
Run Code Online (Sandbox Code Playgroud)
这给了我传入的对象中属性的值,但我现在需要将该值与传入的表达式组合并将其传递给数据库集.
IE浏览器,我试图有效运行的代码是 set.FirstOrDefault(x=>x.Name==valueToFind)如何把matchon表达式(包含x=>x.Name),并结合起来,与将==valueToFind得到x=>x.Name==valueToFind来自他们?
如何构建组合表达式?(我意识到上面的"字符串"代码是完全错误的,但我试图了解我需要该函数做什么,但我不知道那个语法会是什么样子.)
对于手动编码的示例,只需传入带有值集的硬编码lambda就足够了,但是我的用例包括遍历一组对象并找到每个对象的匹配,因此在运行时之前不会知道该值,并且该方法必须对任意类型和各种属性起作用,因此我也不能对属性名称进行硬编码.
如果你有一个属性选择器和一个要比较的值,你可以得到一个这样的表达式树:
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;
}
Run Code Online (Sandbox Code Playgroud)
样品用法:
var comparer = GetComparer<Person, string>(p => p.Name, "John");
var persons = Person.GetPersons();
var john = persons.FirstOrDefault(comparer);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
769 次 |
| 最近记录: |