2012-07-17 88 views
1

我正在使用反射从我的EF4域实体获取EntityCollection<Derived>属性。一个示例实体可能拥有许多具有共同基础的类型的集合。 GetValue()返回object,但我需要将其转换为EntityCollection<Base>或甚至只有IEnumerable<Base>。但是如何? (糟糕,浇铸到IEnumerable的不工作为C#4)无法将类型为EntityCollection的对象<Derived>转换为EntityCollection <Base>

范例模型

public class Derived : Base { ... } 
public class AnotherDerived : Base { ... } 
public class Example : Base 
{ 
    public virtual ICollection<Derived> Items { get; set; } 
    public virtual ICollection<AnotherDerived> OtherItems { get; set; } 
} 

我有很难理解铸造和多态。我想我能成功地做到这一点,反映DbSet<Derived>铸造他们到IQueryable<Base>。但与EntityCollection我无法将反射的对象恢复成可用的形式。

方法

public static List<T> GetCollectedEntities<T>(this BaseEntity entity) 
    where T : BaseEntity 
{ 
    var result = new List<T>(); 
    foreach (var c in GetCollections<T>(entity)) 
     foreach (var item in (EntityCollection<T>)c) //ERROR 
      result.Add(item); 
    return result; 
} 

public static List<object> GetCollections<T>(this BaseEntity entity) 
    where T : BaseEntity 
{ 
    var collections = new List<object>(); 
    var props = from p in entity.GetType().GetProperties() 
       let t = p.PropertyType 
       where t.IsGenericType 
       && t.GetGenericTypeDefinition() == typeof(ICollection<>) 
       let a = t.GetGenericArguments().Single() 
       where a == typeof(T) || a.IsSubclassOf(typeof(T)) 
       select p; 
    foreach (var p in props) 
     collections.Add(p.GetValue(entity, null)); 
    return collections; 
} 

真实世界的错误

Unable to cast object of type 
'System.Data.Objects.DataClasses.EntityCollection`1[HTS.Data.ServiceOrder]' 
to type 
'System.Data.Objects.DataClasses.EntityCollection`1[HTS.Data.IncomingServiceOrderBase]'. 

回答

2

好像之类的事情,你应该能够做到,不是吗?但这是不允许的,这是为什么。

EntityCollection<T>是可写的,因此如果您将EntityCollection<Derived>转换为EntityCollection<Base>,则可以将Base对象插入集合中。这意味着您现在有一个不是派生类的实例,并且不是派生于EntityCollection<Derived>中的子元素。然后怎样呢?一个迭代器EntityCollection<Derived>,预计Derived将会以各种令人兴奋的方式失败。

+0

那么铸造成'IEnumerable '那么呢? – Benjamin 2012-07-17 17:59:14

+0

大声笑我以为我已经尝试过,并得到一个错误。有用。谢谢。 – Benjamin 2012-07-17 18:00:45

+0

如果您使用C#4,则可以进行IEnumerable 的协变分配。它不会在早期版本的.net中工作。请参阅http://msdn.microsoft.com/en-us/library/ee207183.aspx – MNGwinn 2012-07-17 18:01:54

相关问题