如何将继承的属性动态添加到EF数据存储区?

时间:2016-11-08 21:24:09

标签: c# entity-framework system.reflection

this post中,我询问并回答了如何动态导入类和值的值。没有硬编码的EF / DbSet模型中的属性。我无法相信我偶然发现了很长时间以找到一种方法来做到这一点。但...

它揭示了一个问题,即在Locals窗口中查看实例层次结构的数小时无法解决:

虽然我可以在目标类上动态导入数据,但是它所扩展的基类中的任何属性都会失败。上面的帖子最后说明了这一点。在我们将数据导入DataTable之后,我们的问题就出现了。我们将浏览DataTable的列,使用数据库中的匹配类型来确定它们的类型(int,double等)。

要做到这一点,一行创建我们从中查询信息的对象,虽然一切都适用于Child()属性,但一旦我们从Person()(基类)中找到一个,它就失败了null reference。

如果不重新发布整个帖子,我只会粘贴相关位:

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

在上面,最后一行未能为 theProp 分配一个有效对象,而是将其交给null,它会在查询时对我们的程序进行barfs。

上面链接中的示例(此代码段来自)只要 ,您只能从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...

我无法弄清楚为什么孩子的生活()......

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

对于一个完整的,有效的例子 - 失败 - 请参阅the original post here

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

1 个答案:

答案 0 :(得分:1)

thisTypeInfo.GetDeclaredProperty获取类型本身声明的属性,而不是其超类型。使用thisTypeInfo.GetProperty。或者只是

theObj.GetType().GetProperty(entAttrName);
相关问题