2016-11-15 28 views
1

これは、汎用エンティティフレームワークリポジトリクラスの一部として存在する私の方法です。linq式の引数を受け入れるメソッドを呼び出す方法

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[] { }); 
      } 

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

..私は私がmethodInfo.Invokeのパラメータの配列を変更する必要がある知っているが、テストの目的は、静的に呼び出されたときに、それはちょうど空のLINQ式またはこれと同等だったと言うためにmethodInfo.Invoke()で正しいパラメータを指定する方法

私はdbcontextと外部dllにあるエンティティを処理する必要があり、これを自分のアプリケーションプロジェクトに追加することができないため、これを行っています。 。私のアプリケーションでは、アプリケーションのさまざまな配備が異なるバージョンのデータプロバイダdllにアクセスできるように、「サテライト」アセンブリを参照できる必要があります。

ありがとうございました。

+0

式ツリーを構築するために '式*()'メソッドを使用します。 – SLaks

+0

実際の質問は何ですか?これまでのやり方で例外を避けるには? –

+0

今のところ、新しいオブジェクト[] {}は例外を作成しているので、最後のブロックの同等の静的コードと同じように反映させたいだけです(実際にはリポジトリをインスタンス化したDIを介して少しずつ異なって)、すなわちいくつかの結果を得る。それ以外では、私はリフレクションを多用していないか、linqとジェネリックを組み合わせていないので、サンプル式でこのメソッドを呼び出す方法を理解したいと思います。このため、アセンブリのみのエンティティ名(つまり「労働者」)のどのタイプにも直接アクセスすることはできません –

答えて

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 }); 
+0

私の直面する問題をソートしてくれた大変感謝しています。 linq式を作成するための参考資料はありますか?または、私が自分の周りを検索できる最高の条件を知っています。私はラムダ、linq funcの表現は、はいと思った?とにかくすべてのベストありがとう。 –

+0

'Include'式を作成するには、' Expression.Parameter'、 'Expression.PropertyOrField'、' Expression.Lambda'で十分です。参考までに、わかりません - 私はその地域に多くの人の投稿がありますが、それらはすべて自己学習と実験から来ています。 –

関連する問題