如何从未知的实体框架模型确定哪个连接字符串/上下文



如果以前有人问过我,请原谅我的问题,但我不能100%确定我的谷歌措辞是否不准确,或者这只是不正常的事情。

我有一个WCF服务,我需要传入任何类型的实体框架模型对象(未知的事实是,我需要几乎相同地对待这些对象,而不需要为每个模型编写新的接口契约,因为它们都以相同的方式保存,例如)。

到目前为止,这很好。它们被传递进来,我似乎得到了很好的类型(我认为到目前为止),所以我可以"一般地"对待它们。"

我的新难题是:我如何从实体对象获得对数据库连接字符串的引用?

有没有类似的表达方式(请原谅这里的一些极端的假话):

object DbContext = genericEFObject.databaseEntityConnection; //need help here
typeof(DBContext) db = typeof(DBContext); //possibly help here too
db.Entry(genericEFObject).State = System.Data.Entity.EntityState.Added;
db.SaveChanges();

如果可能的话,我想避免将db对象传递给契约。

这里有什么了不起的吗?

我很遗憾地说,没有任何简单的方法可以做到这一点。您将不得不编写大量代码并滥用反射,就像它已经过时一样。在我看来,这些是你的选择:

通用方法

DbContext是而不是被序列化并通过WCF传递。因此,这将留给您一个POCO实体对象来创建,更新或删除或一个漂亮的长表达式树表示查询。然后,您必须弄清楚它属于哪个DbContext,实例化该DbContext,弄清楚它属于哪个DbSet,并通过反射在DbSet上使用它。

代码生成

你仍然需要大量的反射来拉出所有的DbContexts和dbset,但是一旦你有了这些,为它们生成方法应该是轻而易举的。对于应用于不同操作的约定,您将有更大的灵活性。缺点是那里会有很多代码,并且可能会变得有点难以管理,除非您找到某种方法将其分解为不同的命名空间。

通常情况下,答案是否定的-不做一些反射的事情,不可能从实体对象获得上下文实例。让实体知道它们是从哪个存储产生的,这通常被认为是一种不好的做法。

然而,由于实体框架现在(v6.1.1)的实现方式,技术上有一种方法可以在您的上下文配置为创建代理(ProxyCreationEnabled = true)时以"黑客方式"实现这一点。

这是一个非常糟糕的代码,它会给你一个来自实体对象的ObjectContext(警告:do not even consider to use this in production):

var ctx = new MyContext();
ctx.Configuration.ProxyCreationEnabled = true;
dynamic dynamicEntity = ctx.Employees.First();
var entityWrapper = dynamicEntity._entityWrapper;
Type type = entityWrapper.GetType();
var contextProperty = type.GetProperty("Context");
var objectContext = contextProperty.GetValue(entityWrapper) as ObjectContext;

最新更新