如何调用接受linq表达式参数的方法

时间:2016-11-15 16:22:58

标签: c# linq reflection dependency-injection entity-framework-6

这是我的方法,它作为通用实体框架存储库类的一部分存在。

public IList<T> GetAll(params Expression<Func<T, object>>[] navigationProperties)
        {
            List<T> list;

            IQueryable<T> dbQuery = Context.Set<T>();

            //Apply eager loading
            foreach (Expression<Func<T, object>> navigationProperty in navigationProperties)
                dbQuery = dbQuery.Include<T, object>(navigationProperty);

            list = dbQuery
            .AsNoTracking()
            .ToList<T>();
            return list;
        }

我需要通过反射来调用方法,这是我到目前为止所做的。

using (var ctx = (DbContext)Activator.CreateInstance(dbContextType))
            {
                ctx.Configuration.LazyLoadingEnabled = false;

                var curEntityPI = ctx.GetType().GetProperties().Where(pr => pr.Name == "Worker").First();
                var curEntityType = curEntityPI.PropertyType.GetGenericArguments().First();
                var set = ctx.Set(curEntityType);
                Type generic = typeof(DataAccess.Repository.EF.dEfDataRepository<,>);
                Type[] typeArgs = {curEntityType, dbContextType};
                Type constructed = generic.MakeGenericType(typeArgs);
                MethodInfo methodInfo = constructed.GetMethod("GetAll");

                object repositoryInstance = Activator.CreateInstance(constructed, new object[] { ctx });
                var result = methodInfo.Invoke(repositoryInstance,new object[] { });
            }

我知道我需要在methodInfo.Invoke中更改参数数组,但出于测试目的,它说它只是一个空的linq表达式,或者在静态调用时等效于此。

WorkerRepository workerRepositoryInstance = new
WorkerRepository<Worker,MyDbContext>(ctx);
List<Worker> workers = workerRepositoryInstance.GetAll().ToList();

我如何在methodInfo.Invoke()

中提供正确的参数

我这样做是因为我需要使用dbcontext和外部dll中的实体,并且无法在我的应用程序项目中添加对此的引用。我的应用程序需要能够参考卫星&#39;以一种方式组装,即应用程序的不同部署可以访问数据提供者dll的不同版本。

非常感谢你的帮助。

1 个答案:

答案 0 :(得分:1)

如果我理解正确,您需要动态创建Expression<Func<T, object>>的空数组。

您可以使用Array.CreateInstance方法:

var navigationPropertyType = typeof(Expression<>).MakeGenericType(
    typeof(Func<,>).MakeGenericType(curEntityType, typeof(object)));

var navigationProperties = Array.CreateInstance(navigationPropertyType, 0);

var result = methodInfo.Invoke(repositoryInstance, new object[] { navigationProperties });