LINQ:将lambdaexpression式作为要执行的parameter passing并通过方法返回
所以这里是场景:我有一系列不同的存储库类,每个可以使用一个孤立的数据上下文,或一个共享的上下文。 在使用独立上下文的情况下,我希望向基类中添加一个方法,该方法允许我指定lambda作为参数,通过所选资源库的独立上下文来执行该expression式,并返回一个IQueryable结果。 方法签名将如何显示,以及如何将expression式传递给上下文?
我需要的解决scheme尽可能通用,因为任何可能的模型对象/表可以使用。
这里基本上是我想要做的:
IAssetRepository repo = new AssetRepository(true); // true indicates isolated context var results = repo.ExecuteInContext<SomeType>(SomeTable.Where(x => x.SomeProp.Equals(SomeValue)));
像这样的东西:
public IEnumerable<T> ExecuteInContext<T>( Expression<Func<T,bool>> predicate) { ... // do your stuff //eg Table<T> t = GetTable<T>(); return t.Where(predicate); }
要么
public IEnumerable<T> ExecuteInContext<T>( IQueryable<T> src, Expression<Func<T,bool>> predicate) { return src.Where(predicate); }
用法:
var r = repo.ExecuteInContext<SomeType>( x => x.SomeProp.Equals(Somevalue));
要么
var r = repo.ExecuteInContext(GetTable<T>(), x => x.SomeProp.Equals(Somevalue));
假设:
- 表可以从T派生出来,否则你也需要通过源代码。
- 你知道如何修改谓词expression式,如果需要的话。
这是一个完整的工作示例,如何将LINQexpression式作为parameter passing
using System; using System.Linq.Expressions; using System.Reflection; namespace ConsoleTest { public class Values { public int X { get; set; } public int Y { get; set; } public override string ToString() { return String.Format("[ X={0} Y={1} ]", X, Y); } } class Program { static void Main() { var values = new Values {X = 1, Y = 1}; // pass parameter to be incremented as linq expression IncrementValue(values, v => vX); IncrementValue(values, v => vX); IncrementValue(values, v => vY); // Output is: [ X=3 Y=2 ] Console.Write(values); } private static void IncrementValue<T>(T obj, Expression<Func<T,int>> property) { var memberExpression = (MemberExpression)property.Body; var propertyInfo = (PropertyInfo)memberExpression.Member; // read value with reflection var value = (int)propertyInfo.GetValue(obj, null); // set value with reflection propertyInfo.SetValue(obj, ++value, null); } } }
看看PredicateBuilder – http://www.albahari.com/nutshell/predicatebuilder.aspx
这段代码将把你的where子句打包成可以传递的Expression对象。
我已经实现了Repository模式,我的flava是给它一个Fetch(ICriteria)方法,它根据提供的条件构buildWhere子句。 简单,但为我工作。