简体   繁体   English

复制属于IDbSet的属性 <T> 到另一个属于List的类的属性 <T> 用反射相同的名字?

[英]Copy a property that is an IDbSet<T> to a property on another class that is a List<T> with the same names using reflection?

We have a scenario in our unit tests where we have created a FakeDbSet that implements IDbSet. 我们在单元测试中有一个场景,我们创建了一个实现IDbSet的FakeDbSet。 In a FakeUnitOfwork I have properties that are IDbSets and getting new-ed up using the FakeDbSet. 在FakeUnitOfwork中,我有一些IDbSets属性,并使用FakeDbSet进行了新的编辑。

Without having to write out each different property in my Commit method I am trying to use reflection to iterate over the properties inside the FakeUnitOfWork. 无需在我的Commit方法中写出每个不同的属性,我试图使用反射来迭代FakeUnitOfWork中的属性。 I then want to copy the property values to a differnt class that has propertes of List<> of the same type. 然后,我想将属性值复制到具有相同类型的List <>属性的不同类中。 So I may have a property in my FakeUnitOfWork: 所以我的FakeUnitOfWork中可能有一个属性:

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

In my fake data store I have this property: 在我的假数据存储中,我有这个属性:

List<User> Users {get;set;}

This is hwat I have so far: 这是我到目前为止的情况:

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.


            }
}

So, I am not sure how to know I am looking at, say, a IDbSet (from FakeUnitOfWork) and a List (from my fake memory data store) so that I can copy the data from FakeUnitOfWork over to the data store. 所以,我不知道如何知道我正在查看IDbSet(来自FakeUnitOfWork)和List(来自我的伪内存数据存储),以便我可以将数据从FakeUnitOfWork复制到数据存储。 Since they have the same names I only need to figure out how to do the casting via reflection. 由于它们具有相同的名称,我只需要弄清楚如何通过反射进行铸造。

Update: I tried something like this and thought I might be on the irght track, but the code never gets hit: 更新:我试过这样的事情,并认为我可能会在正确的轨道上,但代码永远不会被击中:

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);
                   }


                }

You used a reflection to get types and properties for your context and unit of work. 您使用反射来获取上下文和工作单元的类型和属性。 Now you have property of type List<> on one side and you want to assign content of property of type IDbSet<> to it. 现在,您在一侧具有List<>类型的属性,并且您希望为其分配类型为IDbSet<>的属性的内容。 Is it right? 这样对吗?

The theory 理论

To do that you need to call ToList method on IDbSet<> but this method is not part of IDbSet<> interface. 为此,您需要在IDbSet<>上调用ToList方法,但此方法不是IDbSet<>接口的一部分。 It is extension method defined in System.Linq.Enumerable static class. 它是System.Linq.Enumerable静态类中定义的扩展方法。 Extension method is just static method with syntactic sugar but it can still be called as normal static method. 扩展方法只是具有语法糖的静态方法,但它仍然可以称为常规静态方法。 So you must lookup Enumerable class using reflection (get type), get generic method info for ToList method and target it to proper generic argument (used by current IDbSet<> ). 因此,您必须使用反射(get type)查找Enumerable类,获取ToList方法的通用方法信息,并将其定位到正确的泛型参数(由当前IDbSet<> )。 Then you can pass your set as parameter to this method and invoke it. 然后,您可以将set作为参数传递给此方法并调用它。

Anyway better approach would be avoiding as many reflection as possible. 无论如何,更好的方法是避免尽可能多的反思。 For example expose special interface on TestUnitOfWork which would offer direct access to lists. 例如,在TestUnitOfWorkTestUnitOfWork可以直接访问列表的特殊接口。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM