LINQ:将lambda表达式作为参数传递,由方法执行并返回

Jas*_*zek 50 c# linq

所以这是场景:我有一系列不同的存储库类,每个类都可以使用独立的数据上下文或共享上下文.在使用隔离上下文的情况下,我想向基类添加一个方法,允许我将lambda指定为参数,让该表达式由所选存储库的隔离上下文执行并返回IQueryable结果.方法签名看起来如何,以及如何将表达式传递给上下文?

我需要解决方案尽可能通用,因为可以使用任何可能的模型对象/表.

这基本上是我要做的事情:

IAssetRepository repo = new AssetRepository(true); // true indicates isolated context
var results = repo.ExecuteInContext<SomeType>(SomeTable.Where(x => 
                                              x.SomeProp.Equals(SomeValue)));
Run Code Online (Sandbox Code Playgroud)

lep*_*pie 66

像这样的东西:

public IEnumerable<T> ExecuteInContext<T>(
  Expression<Func<T,bool>> predicate)
{
  ... // do your stuff
  //eg
  Table<T> t = GetTable<T>();
  return t.Where(predicate);
}
Run Code Online (Sandbox Code Playgroud)

要么

public IEnumerable<T> ExecuteInContext<T>(
   IQueryable<T> src, Expression<Func<T,bool>> predicate)
{
  return src.Where(predicate);
}
Run Code Online (Sandbox Code Playgroud)

用法:

var r = repo.ExecuteInContext<SomeType>( 
          x => x.SomeProp.Equals(Somevalue));
Run Code Online (Sandbox Code Playgroud)

要么

var r = repo.ExecuteInContext(GetTable<T>(), 
          x => x.SomeProp.Equals(Somevalue));
Run Code Online (Sandbox Code Playgroud)

假设:

  1. 表可以从T派生,否则您也需要传递源.
  2. 您知道如何在需要时修改谓词表达式.


Mak*_*nko 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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Dun*_*can 6

查看PredicateBuilder - http://www.albahari.com/nutshell/predicatebuilder.aspx

此代码将您的where子句打包为您可以传递的Expression对象.

我已经实现了Repository模式,我的flava是给它一个Fetch(ICriteria)方法,它根据提供的标准构建Where子句.很简单,但对我有用.