如何动态地将继承的属性添加到EF数据存储中? [英] How can I dynamically add inherited properties to EF datastore?

查看:53
本文介绍了如何动态地将继承的属性添加到EF数据存储中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此帖子中,我问并回答了如何动态导入类&的值.无需硬编码的EF/DbSet模型中的属性.我简直不敢相信我会绊倒足够长的时间来找出一种方法来做到这一点.但是...

In this post, I asked and answered how to dynamically import values for classes & properties in an EF/DbSet model with no hard coding. I couldn't believe I stumbled around long enough to figure out one way to do it. But...

它揭示了一个问题,即无法在本地"窗口中浏览实例层次结构数小时:

It revealed a problem that hours of looking through the instance hierarchy in the Locals window couldn't resolve:

虽然我可以在目标类上动态导入数据,但它从基类扩展的任何属性均会失败.上面的第一篇文章最后说明了这一点.在将数据导入到DataTable之后,我们的问题就会显现出来.我们正在遍历DataTable的列,使用数据库中匹配的Types来确定其Type(int,double等).

While I can import data dynamically on the target class, any properties from the base class it extends from fail. The initial post above illustrates this at the end. Our problem shows itself after we've got the data to import into a DataTable. We're going through the columns of the DataTable, using the matching Types in the database to determine their Type (int, double, etc.).

为此,一行创建了一个对象,我们从中查询该信息,尽管对于Child()属性来说一切都很好,但是当我们从Person()(基类)中击中一个对象时,它就会失败并显示一个空引用.

To do that, one line creates the object we query that info from, and while all is well for Child() properties, as soon as we hit one from the Person() (the base class), it fails with a null reference.

在不重新发布整个帖子的情况下,我只会粘贴相关的位:

Without re-posting that whole post, I will only paste the relevant bits:

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,这会在查询程序后立即阻止我们的程序.

Above, this last line fails to assign theProp a valid object, instead handing it a null, which barfs our program as soon as it queries it.

只要您仅从Child()类中导入值,上面链接的示例(此摘录的来源)就可以正常工作.继承的属性使它停止在上面的行.

The example at the link above (where this snippet came from) works fine as long as you only import values from the Child() class. Inherited properties cause it to halt at the line above.

entAttrName只是属性名称的字符串,它取自前面的DataTable的标题行,并且(尽管略过上面的几行代码)本质上类似于:

entAttrName is simply the string of the name of the property, taken from the DataTable's header row earlier, and (while slipping past some lines of code above), essentially does something like:

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

I cannot figure out for the life of my why 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()中的任何属性...

...properties go well through that line, but any of the properties from 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; }
}

...失败.这是程序的完整日志,显示该程序的停止位置.例外情况是在原始帖子中快照的:

...fail. Here is the full log of the program, showing where it halts. The exception is snapshotted at the original post:

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

有关此故障的完整有效示例,请参见原始帖子在这里.

For a full, working example-with this failure-see the original post here.

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

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

推荐答案

thisTypeInfo.GetDeclaredProperty 获取由类型本身(而不是其父类型)声明的属性.使用 thisTypeInfo.GetProperty .或者只是

thisTypeInfo.GetDeclaredProperty gets properties declared by the type itself, not its supertype. Use thisTypeInfo.GetProperty. Or just

theObj.GetType().GetProperty(entAttrName);

这篇关于如何动态地将继承的属性添加到EF数据存储中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆