Suchen Sie dynamisch nach einem generischen DbSet in einem DbContextC#

Ein Treffpunkt für C#-Programmierer
Anonymous
 Suchen Sie dynamisch nach einem generischen DbSet in einem DbContext

Post by Anonymous »

Ich weiß, dass diese Frage bereits gestellt wurde, aber ich konnte keine Antwort finden, die mich zufriedenstellte. Ich versuche, ein bestimmtes DbSet basierend auf dem Namen seines Typs abzurufen.

Ich habe Folgendes:

Code: Select all

[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("MyDllAssemblyName")]
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("MyCallingAssemblyName")]

class MyDbContext : DbContext {

public DbSet A { get; set; }
public DbSet B { get; set; }

public dynamic GetByName_SwitchTest(string name) {
switch (name) {
case "A": return A;
case "B": return B;
}
}

public dynamic GetByName_ReflectionTest(string fullname)
{
Type targetType = Type.GetType(fullname);
var model = GetType()
.GetRuntimeProperties()
.Where(o =>
o.PropertyType.IsGenericType &&
o.PropertyType.GetGenericTypeDefinition() == typeof(DbSet) &&
o.PropertyType.GenericTypeArguments.Contains(targetType))
.FirstOrDefault();
if (null != model)
return model.GetValue(this);
return null;
}
}
Ich habe keine Probleme, den Typ selbst zu erhalten, egal ob über einen einfachen Schalter oder eine Reflexion. Ich muss den Typ jedoch als dynamischen Typ zurückgeben, da ich nicht weiß, um welchen DbSet-Typ es sich handeln wird.
Dann verwende ich es irgendwo anders in derselben Baugruppe folgendermaßen:

Code: Select all

// MyDbContext MyDbContextInstance..
var model = MyDbContextInstance.GetByName_SwitchTest("A");
var record1 = model.FirstOrDefault(); // It crashes here with RunTimeBinderException
An diesem Punkt enthält model eine Instanz eines InternalDbSet-Typs. Von da an erhalte ich bei jeder Verwendung des Modellobjekts eine RunTimeBinderException:
'Microsoft.Data.Entity.Internal.InternalDbSet' enthält keine Definition für 'FirstOrDefault'

Bei meiner Recherche im Web habe ich einen Blog-Beitrag gefunden, der Folgendes erklärt (dixit seinen Blog):


Der Grund für den Aufruf FirstOrDefault() schlägt fehl, weil die Typinformationen
des Modells zur Laufzeit nicht verfügbar sind. Der Grund dafür, dass es nicht
verfügbar ist, liegt darin, dass anonyme Typen nicht öffentlich sind. Wenn die Methode
eine Instanz dieses anonymen Typs zurückgibt, gibt sie ein
System.Object zurück, das auf eine Instanz eines anonymen Typs verweist – einen
Typ, dessen Informationen für das Hauptprogramm nicht verfügbar sind.


Und dann weist er auf eine Lösung hin:


Die Lösung ist eigentlich ganz einfach. Wir müssen lediglich
AssemplyInfo.cs des ClassLibrary1-Projekts öffnen und die folgende
Zeile hinzufügen: [assembly:InternalsVisibleTo("assembly-name")]


Ich habe diese Lösung in meinem Code ausprobiert, aber sie funktioniert nicht. Zur Information: Ich habe eine asp.net 5-Lösung mit zwei Assemblys, die auf dnx dotnet46 laufen. Eine App und eine DLL mit allen meinen Modellen und DbContext. Alle betroffenen Aufrufe, die ich mache, befinden sich jedoch in der DLL.

Hat diese Lösung überhaupt eine Chance, zu funktionieren?
Verpasse ich etwas?
Irgendwelche Hinweise wären sehr willkommen?

Vielen Dank im Voraus

[BEARBEITEN]

Ich habe versucht, zurückzukehren IQueryable statt dynamisch und ich könnte das grundlegende Abfragemodell verwenden.FirstOrDefault(); aber vor allem möchte ich auch in der Lage sein, nach einem Feld zu filtern:

Code: Select all

var record = model.FirstOrDefault(item => item.MyProperty == true);

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post