如何动态地将继承属性添加到EF数据存储
本文关键字:添加 属性 EF 存储 数据 继承 何动态 动态 | 更新日期: 2023-09-27 18:17:05
在这篇文章中,我询问并回答了如何为类动态导入值&属性在EF/DbSet模型中没有硬编码。我简直不敢相信我跌跌撞撞了这么久才找到了一种方法。但是…
它揭示了一个问题,在Locals窗口中查找实例层次结构数小时无法解决:
虽然我可以在目标类上动态导入数据,但它从基类扩展的任何属性都会失败。上面最初的帖子在最后说明了这一点。在我们将数据导入到DataTable之后,问题就显现出来了。我们将遍历DataTable的列,使用数据库中匹配的Types来确定它们的类型(int、double等)。
要做到这一点,一行创建了我们查询信息的对象,虽然Child()属性一切正常,但一旦我们从Person()(基类)中命中一个,它就会失败,并产生一个空引用。
不重新发布整篇文章,我只粘贴相关的部分:
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,这使得我们的程序在查询它的时候就停止了。
只要只从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
有关完整的工作示例(包含此失败),请参阅此处的原始帖子。
===========================================================================
thisTypeInfo.GetDeclaredProperty
获取由类型本身声明的属性,而不是它的超类型。使用thisTypeInfo.GetProperty
。或者只是
theObj.GetType().GetProperty(entAttrName);