So stellt sich heraus, dass der Entitätstyp zur Kompilierungszeit buchstäblich nicht bekannt oder bekannt ist. Es muss eine Zeichenfolge sein.
Der einzige Ort, an dem Sie den Typ zum Zeitpunkt der Kompilierung verwenden, ist in der Besetzung (DbSet<tableEntity>)
. Nun, du brauchst das vielleicht nicht. Alles, was Sie von diesem Typ benötigen, ist der Aufruf AsQueryable()
, und AsQueryable()
ist eine Erweiterungsmethode für IEnumerable
, mit generischen und nicht-generischen Versionen. Wenn wir es durch nicht-generische IEnumerable
aufrufen, das ist nicht-generisch AsQueryable()
, die nicht generische IQueryable
zurückgibt. Aber wir geben sowieso object
zurück, also hey. Damit das Ergebnis dieser Sache nützlich ist, muss etwas irgendwo eine Reflexion darüber anstellen, so dass der erklärte Typ wahrscheinlich von geringer Bedeutung ist.
sehen, ob das funktioniert:
public object GetList(string tableEntity)
{
Type tableEntity = Type.GetType("TestProject." + typeName + ", TestProject");
var dbObject = (System.Collections.IEnumerable)
typeof(DbContext).GetMethod("Set", Type.EmptyTypes)
.MakeGenericMethod(tableEntity)
.Invoke(databaseContext, null);
return dbObject.AsQueryable();
}
Wenn Sie generische IQueryable<TEntityType>
brauchen sich herausstellt, werden wir haben Reflektion verwenden MethodInfo
für AsQueryable<TEntityType>
für das Unbekannte zu erhalten (zum Zeitpunkt der Kompilierung) Entitätstyp und Anruf MakeGenericMethod(tableEntity)
auf das.
Erster Versuch:
In der Sprache, geben Sie Parameter für Generika müssen tatsächlichen Typen, nicht Instanzen der Type
Klasse sein. Das liegt daran, dass sie zur Kompilierzeit aufgelöst werden.
Aber das ist kein Problem; Um einen Typparameter an eine generische Methode zu übergeben, schreiben Sie einfach eine generische Methode mit einem Typparameter.
Sie können dies nicht tun:
var stuff = GetList("MyTableEntityClass");
Aber das ist nur so gut:
var stuff = GetList<MyTableEntityClass>();
...
public object GetList<TTableEntity>()
{
var dbObject = (DbSet<TTableEntity>)typeof(DbContext)
.GetMethod("Set", Type.EmptyTypes)
.MakeGenericMethod(typeof(TTableEntity))
.Invoke(databaseContext, null);
return dbObject.AsQueryable();
}
Reflexion unterscheidet; deshalb übergeben wir typeof(TTableEntity)
zu MakeGenericMethod()
.
Und wenn wir eine tatsächliche Art verwenden, dass der Compiler überprüfen können, können wir es besser machen mit unserem Rückgabetyp zu:
public IQueryable<TTableEntity> GetList<TTableEntity>()
{
var dbObject = (DbSet<TTableEntity>)typeof(DbContext)
.GetMethod("Set", Type.EmptyTypes)
.MakeGenericMethod(typeof(TTableEntity))
.Invoke(databaseContext, null);
return dbObject.AsQueryable();
}
Der Unterschied zwischen der Kompilierung und Laufzeit ist sehr wichtig! Wenn du es nicht kaputt machst, stolpertst du ständig über so schlimme Fallstricke wie diese. [Lesen Sie eine Einführung in Compiler.] (Https://meta.stackexchange.com/questions/25840/can-we-stop-recommending-the-dragon-book-please) Es ist das Werkzeug, mit dem Sie professionell arbeiten, Sie sollte wissen, wie es im Prinzip funktioniert, wenn nicht im Detail. –
Sie können die folgenden nützlich finden, wenn die DB MS Sql Server ist oder die gleichen Datentypdefinitionen hat: https://stackoverflow.com/a/28561947/4228193. System.Web aller Orte. Ich verwende es wie folgt 'TypeCode systc = Parameter.ConvertDbTypeToTypeCode ([SqlMetaData_instance] .DbType); versuchen { Rückgabe Convert.ChangeType (val, systc); } ' – mpag