所以这是场景:我有一系列不同的存储库类,每个类都可以使用独立的数据上下文或共享上下文。在使用隔离上下文的情况下,我想向基类添加一个方法,允许我将lambda指定为参数,让该表达式由所选存储库的隔离上下文执行并返回IQueryable结果。方法签名看起来如何,以及如何将表达式传递给上下文?
我需要解决方案尽可能通用,因为可以使用任何可能的模型对象/表。
这基本上是我要做的事情:
IAssetRepository repo = new AssetRepository(true); // true indicates isolated context
var results = repo.ExecuteInContext<SomeType>(SomeTable.Where(x =>
x.SomeProp.Equals(SomeValue)));
答案 0 :(得分:64)
这样的事情:
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));
假设:
答案 1 :(得分:12)
以下是如何将LINQ表达式作为参数传递的完整工作示例
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 => v.X);
IncrementValue(values, v => v.X);
IncrementValue(values, v => v.Y);
// 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);
}
}
}
答案 2 :(得分:6)
查看PredicateBuilder - http://www.albahari.com/nutshell/predicatebuilder.aspx
此代码将您的where子句打包为可以传递的Expression对象。
我已经实现了Repository模式,我的flava是给它一个Fetch(ICriteria)方法,它根据提供的标准构建Where子句。很简单,但对我有用。