【发布时间】:2014-09-15 07:52:42
【问题描述】:
我有一个有很多 IDbSet<SomeClass> 类型属性的类:
public InMemoryContext : IContext
{
public IDbSet<ClassA> ClassASet { get; set; }
public IDbSet<ClassB> ClassBSet { get; set; }
[...]
public void SaveChanges()
{
//TODO: this is relevant part
}
}
所有这些属性都在构造函数中实例化:
public InMemoryContext
{
ClassASet = new InMemoryDbSet<ClassA>();
[...]
}
InMemoryDbSet 对此问题有一种相关方法:
public class InMemoryDbSet<T> : IDbSet<T> where T : class
{
public void SaveChanges()
{
[...]
}
}
我想获取所有IDbSet 的属性并循环调用SaveChanges(),因此我不需要第二次重复所有集合名称。
我尝试了反射,但由于我的属性是通用的,我无法让它工作。我尝试使ClassA 和ClassB 派生自相同的通用接口,但仍然没有运气。
是否真的可以在不明确指定所有集合的情况下做到这一点?我应该改变什么来达到这个结果?
我想象伪代码是这样的:
public void SaveChanges()
{
foreach(var set in GetDbSetsFromClass(this))
{
set.SaveChanges();
}
}
我尝试了反射:
public void SaveChanges()
{
SaveChangesCalled = true;
var properties = GetType().GetProperties().Where(p => p.PropertyType.IsInterface && typeof(IDbSet<IEntity>).IsAssignableFrom(p.PropertyType)).Cast<InMemoryDbSet<IEntity>>();
foreach (var property in properties)
{
CallSaveChanges(property);
}
}
而且列表是空的 公共布尔 SaveChangesCalled { 获取;放; }
private static void CallSaveChanges<T>(InMemoryDbSet<T> set) where T : class
{
set.SaveChanges();
}
编辑:公共属性必须在 InMemoryContext 类的顶层保持可见,因为这受到定义 EF 上下文的接口的限制。
【问题讨论】:
-
“我尝试了反射” - 反射应该可以工作,你尝试了什么?
-
集合有
SaveChanges方法吗?我在文档中找不到它?IDbSet<T>发布接口定义是什么。 -
InMemoryDbSet具有代码中显示的内容。IDbSet没有。这是我认为最难的部分。
标签: c# generics reflection covariance