2016-11-08 1 views
0

In this post, ich fragte und beantwortete, wie Sie Werte für Klassen & Eigenschaften in einem EF/DbSet-Modell mit keiner harten Codierung dynamisch importieren. Ich konnte nicht glauben, dass ich lange genug herumgestolpert bin, um einen Weg dafür zu finden. Aber ...Wie kann ich dem EF-Datenspeicher geerbte Eigenschaften dynamisch hinzufügen?

Es zeigte sich ein Problem, das Stunden der Suche durch die Instanz-Hierarchie in dem Lokalfenster nicht lösen konnte:

Während ich Daten dynamisch auf der Zielklasse importieren, werden alle Eigenschaften von der Basisklasse es erstreckt sich von scheitern. Der erste Beitrag oben veranschaulicht dies am Ende. Unser Problem zeigt sich, nachdem wir die Daten in eine DataTable importieren. Wir gehen durch die Spalten der DataTable und verwenden die übereinstimmenden Typen in der Datenbank, um ihren Typ zu bestimmen (int, double usw.).

Dafür erstellt eine Zeile das Objekt, von dem wir die Informationen abfragen, und während alles für die Child() -Eigenschaften gut ist, schlägt es mit einem von der Person() (der Basisklasse) fehl eine Nullreferenz.

ohne Re-Posting, dass ganz Post, ich werde nur die entsprechenden Bits einfügen:

foreach (DataRow dr in dt.Rows) 
{ 
    i = 0; // I don't like to put var instantiation in a loop... 
    // each drItem is the content for the row (theObj) 
    foreach (string drItem in dr.ItemArray) 
    { 
     string entAttrName = dt.Columns[i].ToString(); 
     string entAttrValue = dr[i].ToString(); 
     // column (property) name: 
     // the value of that property to load into this class' property 
     // which type of data is this property? (string, int32, double...) 
     // -also has data like if nullable, etc. of use in later refinements... 
     TypeInfo thisTypeInfo = theObj.GetType().GetTypeInfo(); 
     // All details from the property to update/set: 

>>---> PropertyInfo theProp = thisTypeInfo.GetDeclaredProperty(entAttrName); 

Oben, diese letzte Zeile nicht theProp ein gültiges Objekt zuweisen, anstatt es eine Null-Übergabe, die barfs unser Programm, sobald es abfragt.

Das Beispiel am obigen Link (woher dieses Snippet kam) funktioniert gut solange Sie nur Werte aus der Child() -Klasse importieren. Vererbte Eigenschaften bewirken, dass es in der darüber liegenden Zeile anhält.

entAttrName ist einfach die Zeichenfolge des Namen der Eigenschaft, von der früheren Kopfzeile der Datentabelle entnommen und (während vorbei an einigen Codezeilen oben rutschen), hat im Wesentlichen so etwas wie:

var aClass = u.CreateInstanceOf(dt.TableName, pathToAssembly); 
DbSet dbs = ctx.Set(aClass.GetType()); 
var theObj = dbs.Create(aClass.GetType()); 
foreach (DataRow dr in dt.Rows)... 
foreach (string drItem in dr.ItemArray)... 
string entAttrName = dt.Columns[i].ToString(); 
string entAttrValue = dr[i].ToString(); 
TypeInfo thisTypeInfo = theObj.GetType().GetTypeInfo(); 
PropertyInfo theProp = thisTypeInfo.GetDeclaredProperty(entAttrName); ****** 
if (theProp.PropertyType.ToString() == "System.String") 
{ 
    theProp.SetValue(theObj, (String)entAttrValue); 
} 
else if (theProp.PropertyType.ToString().Contains("System.Int32")) 
{ 
    theProp.SetValue(theObj, int.Parse(entAttrValue)); 
} else if... 

kann ich nicht herauszufinden, für das Leben meines warum Child() ...

class Child : Person 
{ 
    [Key] 
    [Column(Order = 0)] 
    public int Id { get; set; } 
    public string sChildFoo { get; set; } 
    public int iChildBar { get; set; } 
    public double dChildBaz { get; set; } 
} 

... Eigenschaften lassen sich gut durch diese Linie, aber eine der Eigenschaften von Person() ...

public abstract class Person 
{ 
    [Key] 
    public int PersonId { get; set; } 
    public int PersonAge { get; set; } 
    public int PersonWeight { get; set; } 
    public string PersonName { get; set; } 
} 

... fehlgeschlagen. Hier ist das vollständige Protokoll des Programms, das anzeigt, wo es anhält. Die Ausnahme in der ursprünglichen Post Snapshot von ihr erstellt wird:

2016-11-08 15:03:12.9049 INFO Starting at 3:03:12 PM 
2016-11-08 15:03:12.9801 INFO Created .Name: Qeququ Qequququ 
2016-11-08 15:03:12.9838 INFO Created .sParentFoo: Kakikikiki 
2016-11-08 15:03:13.9918 INFO wb.WorkSheets count: 2 
2016-11-08 15:03:14.0007 INFO ws.Rows count: 3 
2016-11-08 15:03:14.0007 INFO dt.Rows.Count: 2 
2016-11-08 15:03:14.0007 INFO dt.Name: Child 
2016-11-08 15:03:14.0666 INFO aClass.FullName: DynamicEFLoading.Child 
2016-11-08 15:03:14.0666 INFO Creating 'dbs' object... 
2016-11-08 15:03:14.0891 INFO GetType: DynamicEFLoading.Child 
2016-11-08 15:03:14.0963 INFO ================= row ================================== 
2016-11-08 15:03:14.0963 INFO ================= col 0 
2016-11-08 15:03:14.1105 INFO [0] Item: sChildFoo 
2016-11-08 15:03:14.1105 INFO [0] Value: Norwich 
2016-11-08 15:03:14.1105 INFO theProp.DeclaringType.FullName of attr: DynamicEFLoading.Child 
2016-11-08 15:03:14.1265 INFO theProp.GetSetMethod(true).ToString() of attr: Void set_sChildFoo(System.String) 
2016-11-08 15:03:14.1265 INFO theProp.GetType().ToString() of attr: System.Reflection.RuntimePropertyInfo 
2016-11-08 15:03:14.1265 INFO theProp.Name of attr: sChildFoo 
2016-11-08 15:03:14.1424 INFO theProp.PropertyType.ToString() of attr: System.String 
2016-11-08 15:03:14.1424 INFO theProp.ReflectedType.ToString() of attr: DynamicEFLoading.Child 
2016-11-08 15:03:14.1424 INFO theProp.ReflectedType.ToString() of attr: System.Void 
2016-11-08 15:03:14.1557 DEBUG Set System.String value: Norwich 
2016-11-08 15:03:14.1557 INFO ================= col 1 
2016-11-08 15:03:14.1557 INFO [1] Item: iChildBar 
2016-11-08 15:03:14.1780 INFO [1] Value: 29884 
2016-11-08 15:03:14.1780 INFO theProp.DeclaringType.FullName of attr: DynamicEFLoading.Child 
2016-11-08 15:03:14.1919 INFO theProp.GetSetMethod(true).ToString() of attr: Void set_iChildBar(Int32) 
2016-11-08 15:03:14.2113 INFO theProp.GetType().ToString() of attr: System.Reflection.RuntimePropertyInfo 
2016-11-08 15:03:14.2113 INFO theProp.Name of attr: iChildBar 
2016-11-08 15:03:14.2233 INFO theProp.PropertyType.ToString() of attr: System.Int32 
2016-11-08 15:03:14.2368 INFO theProp.ReflectedType.ToString() of attr: DynamicEFLoading.Child 
2016-11-08 15:03:14.2368 INFO theProp.ReflectedType.ToString() of attr: System.Void 
2016-11-08 15:03:14.2607 DEBUG Set System.Int32 value: 29884 
2016-11-08 15:03:14.2657 INFO ================= col 2 
2016-11-08 15:03:14.2851 INFO [2] Item: dChildBaz 
2016-11-08 15:03:14.2978 INFO [2] Value: 1.2 
2016-11-08 15:03:14.3184 INFO theProp.DeclaringType.FullName of attr: DynamicEFLoading.Child 
2016-11-08 15:03:14.3305 INFO theProp.GetSetMethod(true).ToString() of attr: Void set_dChildBaz(Double) 
2016-11-08 15:03:14.3305 INFO theProp.GetType().ToString() of attr: System.Reflection.RuntimePropertyInfo 
2016-11-08 15:03:14.3457 INFO theProp.Name of attr: dChildBaz 
2016-11-08 15:03:14.3682 INFO theProp.PropertyType.ToString() of attr: System.Double 
2016-11-08 15:03:14.3910 INFO theProp.ReflectedType.ToString() of attr: DynamicEFLoading.Child 
2016-11-08 15:03:14.4098 INFO theProp.ReflectedType.ToString() of attr: System.Void 
2016-11-08 15:03:14.4098 DEBUG Set System.Double value: 1.2 
2016-11-08 15:03:14.4098 INFO ================= col 3 
2016-11-08 15:03:14.4382 INFO [3] Item: PersonAge 
2016-11-08 15:03:14.4609 INFO [3] Value: 34 

Für eine vollständige, funktionierendes Beispiel-mit diesem fehler siehe the original post here.

============================================== ==========================

+1

'thisTypeInfo.GetDeclaredProperty' ruft Eigenschaften ab, die vom Typ selbst deklariert werden, nicht vom Obertyp. Verwenden Sie 'thisTypeInfo.GetProperty'. –

+0

@GertArnold --- du hast es geschafft! Das hat das Problem der geerbten Eigenschaften gelöst! Ich meine es ernst, wenn ich sage, dass ich keine Ahnung habe, wie weit ich gekommen bin. Es durchläuft jetzt alle Eigenschaften !!! Du verdienst die Antwort!Werden Sie eine Antwort posten? Sie können folgendes einfügen: '// Alle Details aus der zu aktualisierenden Eigenschaft: // PropertyInfo theProp = thisTypeInfo.GetDeclaredProperty (entAttrName); PropertyInfo theProp = thisTypeInfo.GetProperty (entAttrName); '(gut, das hat überhaupt nicht gut funktioniert ...) –

Antwort

1

thisTypeInfo.GetDeclaredProperty Ruft Eigenschaften deklariert durch den Typ selbst, nicht seine Supertype. Verwenden Sie thisTypeInfo.GetProperty. Oder einfach

theObj.GetType().GetProperty(entAttrName); 
+0

Nochmals vielen Dank !!! –

Verwandte Themen