Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 读取引用实体的值';使用EF4的s属性信息_C#_Reflection_Entity Framework 4_Entity Framework 4.1 - Fatal编程技术网

C# 读取引用实体的值';使用EF4的s属性信息

C# 读取引用实体的值';使用EF4的s属性信息,c#,reflection,entity-framework-4,entity-framework-4.1,C#,Reflection,Entity Framework 4,Entity Framework 4.1,我希望动态读取在父实体的PropertyInfos中循环时遇到的EntityObjects的PropertyInfos的值(连接到当前Image实例的ImageType实例的列值,f.I.) 主实体的类型只有在运行时才知道,因此我正在寻找一种读取任何被引用实体对象的PropertyInfo值的通用方法 我可以循环子实体的PropertyInfos,但是当我尝试获取一个值时,我得到一个TargetException:对象与目标类型不匹配 // loop through the main entit

我希望动态读取在父实体的PropertyInfos中循环时遇到的EntityObjects的PropertyInfos的值(连接到当前Image实例的ImageType实例的列值,f.I.)

主实体的类型只有在运行时才知道,因此我正在寻找一种读取任何被引用实体对象的PropertyInfo值的通用方法

我可以循环子实体的PropertyInfos,但是当我尝试获取一个值时,我得到一个TargetException:对象与目标类型不匹配

// loop through the main entity's properties
foreach (PropertyInfo pi in entityType.GetProperties())
{
    // if the main entity's property is an entity
    if (pi.PropertyType.BaseType == typeof(System.Data.Objects.DataClasses.EntityObject))
    {
        // loop through the sub entity's properties
        foreach(PropertyInfo mychildren in pi.PropertyType.GetProperties())     
        {   
            // the loop works fine but when i try to get a value I get a
            // TargetException: Object does not match target type.
            object test = mychildren.GetValue(pi, null);
        }
    }
}
我该怎么做

编辑

EntityFramework4.0似乎不允许动态检索实体相关实体的实例。但是使用EF4.1及更高版本,您可以使用它们的类名作为字符串标识符。因此,我升级到EF4.2并使其正常工作

我想要这段代码的原因是在我的DTO翻译例程中使用它。我的DTO可以具有与相关实体的名称属性相对应的字符串属性,这样我就可以访问这些属性,而无需硬编码相关实体的类型

在EF4.1及更高版本中,ObjectContext由一个名为DbContext的类包装,该类提供导航属性,用于使用字符串获取相关实体的实例。要动态检索单个相关实体,可以使用:

动态重新对象=Activator.CreateInstance(重新对象类型)

REOBJECT=context.Entry(currentObject).Reference(REOBJECTTYPE.Name).CurrentValue

对于从4.0升级的用户:建议使用DbContext的方法不是使用EntityObjects,而是使用POCO。可以手动创建,也可以通过edmx上下文菜单生成

我目前的执行情况如下:

// Loop through the propertyinfos of the dto's type
foreach (PropertyInfo pf in dtoType.GetProperties().Where(p => p.CanWrite))
{
    // Use the name of the dto property to get the corresponding property from the POCO's type. If it doesn't exist, pi will be null
    PropertyInfo pi = pocoType.GetProperty(pf.Name, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);

    if (pi != null)
    {
        // Check if the current propertyinfo of the POCO has a subproperty named Id
        // If this is the case we treat the propertyinfo as a referenced POCO
        if (pi.PropertyType.GetProperty("Id") != null)
        {
            // skip referenced POCOs if their data is not needed
            if (!includeRelated) continue;

            // Get the type of the referenced POCO
            Type refObjectType = pi.PropertyType;
            // Create an instance of the referenced POCO
            dynamic refObject = Activator.CreateInstance(refObjectType);

            // Create a type of GenericRepository<objectType>
            Type refObjectRepositoryType = typeof(GenericRepository<>).MakeGenericType(refObjectType);
            // Create an instance of GenericRepository<objectType>
            dynamic refObjectRepository = Activator.CreateInstance(refObjectRepositoryType);

            // Fill the dynamic POCO instance with the values of the referenced POCO instance
            refObject = refObjectRepository._context.Entry(poco).Reference(refObjectType.Name).CurrentValue;

            try
            {
                // Set the dto property with the name value of the referenced POCO instance
                // (i.e. dtoImage.ImageType = pocImage.ImageType.Name)
                pf.SetValue(dto, refObject.Name, null);
            }
            catch (RuntimeBinderException)
            {
                // this happens when the related entity is null, ie. in one to zero-or-one relationships
                continue;
            }

            continue;
        }

        // If the propertyinfo's propertytype does not have an Id property, just set the value of  
        // the dto property to that of the POCO's propertyinfo directly
        pf.SetValue(dto, pi.GetValue(poco, null), null);

    }
}
//遍历dto类型的属性inFos
foreach(dtoType.GetProperties()中的PropertyInfo pf,其中(p=>p.CanWrite))
{
//使用dto属性的名称从POCO的类型中获取相应的属性。如果它不存在,pi将为null
PropertyInfo pi=pocoType.GetProperty(pf.Name,BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
如果(pi!=null)
{
//检查POCO的当前属性INFO是否具有名为Id的子属性
//如果是这种情况,我们将propertyinfo视为引用的POCO
if(pi.PropertyType.GetProperty(“Id”)!=null)
{
//如果不需要引用的POCO的数据,则跳过它们
如果(!includeRelated)继续;
//获取引用的POCO的类型
类型REOBJECTTYPE=pi.PropertyType;
//创建引用的POCO的实例
动态重新对象=Activator.CreateInstance(重新对象类型);
//创建一种类型的GenericRepository
Type ReObjectRepositoryType=typeof(GenericRepository)。MakeGenericType(ReObjectType);
//创建GenericRepository的实例
dynamic ReObjectRepository=Activator.CreateInstance(ReObjectRepositoryType);
//用引用的POCO实例的值填充动态POCO实例
REOBJECT=REOBJECTRepository.\u context.Entry(poco).Reference(REOBJECTTYPE.Name).CurrentValue;
尝试
{
//使用引用的POCO实例的名称值设置dto属性
//(即dtoImage.ImageType=pocImage.ImageType.Name)
设置值(dto,REOBJECT.Name,null);
}
捕获(RuntimeBinderException)
{
//当相关实体为空时,即在一对零或一关系中,会发生这种情况
继续;
}
继续;
}
//如果propertyinfo的propertytype没有Id属性,只需设置
//dto属性直接转换为POCO的propertyinfo属性
设置值(dto,pi.GetValue(poco,null),null);
}
}

目前,此代码仅适用于同时具有Id和Name属性的引用实体。此外,这种方法可能会导致性能损失,因此我实现了includeRelated标志,以切换是否查询相关对象。

您试图从父级的
属性info
获取值,但
GetValue
预期对象为
pi.PropertyType
类型。您应该使用如下内容:

using (var context = new MyContext())
{
    var cust = context.Customer.First();
    var custType = cust.CustomerType;

    var pi = typeof (Customer).GetProperty("CustomerType");
    var child = pi.PropertyType.GetProperty("CustomerTypeID");

    var res = child.GetValue(custType, null);
    // this returns value of Customer.CustomerTypeID
}

感谢您指出这一点,在我的EF 4.0尝试中,我使用GetValue的方式是错误的。我应该使用pi.PropertyType的当前实例,而不是使用propertyinfo pi作为第一个参数。尽管如此,EF4仍然不允许我动态获取该实例,但我的文章的初始版本可能对此有点模糊。