簡體   English   中英

如何動態地將繼承的屬性添加到EF數據存儲中?

[英]How can I dynamically add inherited properties to EF datastore?

本文中 ,我問並回答了如何在不進行硬編碼的情況下動態導入EF / DbSet模型中的類和屬性的值。 我簡直不敢相信我會絆倒足夠長的時間來找出一種方法來做到這一點。 但...

它揭示了一個問題,即在“本地”窗口中瀏覽實例層次結構的時間無法解決:

雖然我可以在目標類上動態導入數據,但它從基類擴展的任何屬性都將失敗。 上面的第一篇文章最后說明了這一點。 在將數據導入到DataTable之后,我們的問題就會顯現出來。 我們正在遍歷DataTable的列,使用數據庫中匹配的Types來確定其Type(int,double等)。

為此,一行創建了一個我們從中查詢該信息的對象,盡管對於Child()屬性來說一切都很好,但是當我們從Person()(基類)中擊中一個對象時,它就會失敗並返回null引用。

在不重新發布整個帖子的情況下,我將僅粘貼相關的內容:

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);

上面的最后一行未能為Prop分配一個有效的對象,而是將其交給了null,這使我們的程序在查詢它時就被拒絕。

只要您僅從Child()類中導入值,以上鏈接(此摘錄的來源)上的示例就可以正常工作。 繼承的屬性使它停在上面的行。

entAttrName只是屬性名稱的字符串,取自之前的DataTable的標頭行,並且(雖然略過了上面的幾行代碼)在本質上類似:

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...

我無法弄清楚我為什么選擇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; }
}

...屬性可以順利通過,但是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; }
}

...失敗。 這是程序的完整日志,顯示它在何處停止。 該異常在原始帖子中快照:

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

有關完整的工作示例(發生此故障),請參見此處的原始文章

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

thisTypeInfo.GetDeclaredProperty獲取由類型本身(而不是thisTypeInfo.GetDeclaredProperty類型)聲明的屬性。 使用thisTypeInfo.GetProperty 要不就

theObj.GetType().GetProperty(entAttrName);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM