1

hi dies ist meine Methode, die als Teil einer generischen Entity-Framework-Repository-Klasse existiert.So rufen Sie eine Methode auf, die linq-Ausdruckargumente akzeptiert

Ich muss die Methode über Reflexion aufrufen und das ist, was ich bisher getan habe.

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

Ich weiß, ich brauche die Parameter-Array in MethodInfo.Invoke zu ändern, aber für Testzwecke sagen, es ist nur ein leeres Linq Ausdruck oder das Äquivalent davon war, wenn statisch genannt ..

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

Wie würde ich den richtigen Parameter in methodInfo.Invoke() liefern

Ich mache dies, weil ich mit einem dbcontext und Entities arbeiten müssen, die in einer externen DLL sind und keine Referenz zu diesem in meinem Anwendungsprojekt hinzufügen können . Meine Anwendung muss in der Lage sein, die "Satelliten" -Assembly so zu referenzieren, dass verschiedene Implementierungen der Anwendung auf verschiedene Versionen der Data-Provider-DLL zugreifen können.

Vielen Dank für Ihre Hilfe.

+0

Verwenden Sie die 'Expression *()' Methoden einen Ausdrucksbaum zu bauen. – SLaks

+0

Was ist die eigentliche Frage? Um eine Ausnahme in dem, was Sie bisher gemacht haben, zu vermeiden? –

+0

Für jetzt ja, das neue Objekt [] {} erstellt eine Ausnahme, also möchte ich nur so weit durch Reflexion gehen wie der äquivalente statische Code im letzten Block (vorausgesetzt, ich habe es korrekt eingegeben, da ich tatsächlich meine Repositories instanziiert habe) anderswo etwas anders durch DI), dh einige Ergebnisse bekommen. Darüber hinaus würde ich gerne verstehen, wie ich diese Methode mit einem Beispielausdruck aufrufen würde, da ich nicht viel mit Reflektion getan habe oder Linq und Generika auch nicht kombiniere. Dafür werde ich keinen direkten Zugriff auf alle Typen in den Assembly-Only-Entity-Namen, d. H. "Worker" –

Antwort

1

Wenn ich richtig verstehe, müssen Sie dynamisch ein leeres Array von erstellen.

Sie können Array.CreateInstance Methode dafür verwenden.

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

Vielen Dank Ivan, die mein unmittelbares Problem sortiert. Haben Sie gute Referenzen zum Erstellen von linq-Ausdrücken? Oder wissen, was die besten Begriffe sind, die ich selbst suchen könnte. Ich dachte Lambda, linq func Ausdruck ja? Danke trotzdem alles Gute. –

+0

'Expression.Parameter',' Expression.PropertyOrField' und 'Expression.Lambda' sollten ausreichen, um' Include' Ausdrücke zu erzeugen. Als Hinweis, ich weiß es nicht - ich habe viele SO-Beiträge in diesem Bereich, aber alles kommt aus dem Selbstlernen und Experimentieren. –

Verwandte Themen