使用反射将属于IDbSet <t>的属性复制到另一个具有相同名称的List <t>的类上的属性</t> </t>

时间:2011-12-11 18:04:27

标签: c# reflection entity-framework-4.1

我们在单元测试中有一个场景,我们创建了一个实现IDbSet的FakeDbSet。在FakeUnitOfwork中,我有一些IDbSets属性,并使用FakeDbSet进行了新的编辑。

无需在我的Commit方法中写出每个不同的属性,我试图使用反射来迭代FakeUnitOfWork中的属性。然后,我想将属性值复制到具有List&lt;&gt;属性的不同类中。相同类型。所以我的FakeUnitOfWork可能有一个属性:

IDbSet<User> Users {get {return _users ?? (_users = new FakeDbSet<User>());}

在我的假数据存储中,我有这个属性:

List<User> Users {get;set;}

到目前为止,这是我所做的:

public void Commit()
{ 
     foreach (var property in typeof(TestUnitOfWork).GetProperties())
            {
               var testContextType = typeof (TestDataContext).GetProperty(property.Name);
//I then want to do a ToList() on the TestUnitOfWork IDbSet properties to push them into the TestDataContext.


            }
}

所以,我不知道如何知道我正在查看IDbSet(来自FakeUnitOfWork)和List(来自我的伪内存数据存储),以便我可以将数据从FakeUnitOfWork复制到数据存储。由于它们具有相同的名称,我只需要弄清楚如何通过反射进行转换。

更新:我尝试过这样的事情并认为我可能会处于不确定的轨道上,但代码永远不会受到影响:

foreach (var property in typeof(TestUnitOfWork).GetProperties())
                {
                   var testContextType = typeof (TestDataContext).GetProperty(property.Name);
                   if(property.GetValue(this,null) is IDbSet<MyBaseEntityType>)
                   {
                        testContextType.SetValue(TestDataContext, ((IDbSet<MyBaseEntityType>) property.GetValue(this,null)).ToList(),null);
                   }


                }

1 个答案:

答案 0 :(得分:2)

您使用反射来获取上下文和工作单元的类型和属性。现在,您在一侧拥有类型为List<>的属性,并且您希望为其分配类型为IDbSet<>的属性的内容。是不是?

理论

为此,您需要在ToList上调用IDbSet<>方法,但此方法不属于IDbSet<>界面。它是System.Linq.Enumerable静态类中定义的扩展方法。扩展方法只是具有语法糖的静态方法,但它仍然可以称为常规静态方法。因此,您必须使用反射(获取类型)查找Enumerable类,获取ToList方法的通用方法信息,并将其定位到正确的通用参数(由当前IDbSet<>使用)。然后,您可以将set作为参数传递给此方法并调用它。

无论如何,更好的方法是避免尽可能多的反思。例如,在TestUnitOfWork上公开可以直接访问列表的特殊界面。