我在使用EF Code First的winforms应用程序中运行了一个类。 DbContext是通过类构造函数通过DI创建的。一切顺利。
问题是被引用的数据也正在通过网站进行修改,使用与EF Code First相同的DI模式,并且数据更改未反映在winforms应用程序的上下文实例中。
我可以通过每次访问时在winforms中重新创建DbContext对象来解决这个问题,但对我来说似乎更像是一个服务位置模式?
是否有真正的DI技术来实现这一目标? 或者我应该从DI中删除上下文并使用服务位置?
答案 0 :(得分:0)
您对其他问题的答案不满意(http://stackoverflow.com/questions/7657643/how-to-force-ef-code-first-to-query-the-database)建议使用分离,AsNoTracking或覆盖更改?
1)也许你可以传递一个能够创建DbContext而不是上下文本身的界面。
using(var context = _contextFactory.Create()) {
var entity = from table in context.Blah...;
}
Create方法可以自己创建具体类(稍微破坏DI模式),也可以使用服务位置为其创建一个。不是很好,但它比在任何地方嵌入服务位置调用更好,但仍然意味着你自己控制生命周期。
2)将WinForm更改为从网站运行的Web服务中读取,实际上类似于禁用缓存。
3)深入MVC的核心(实际上并不是那么深)它直接引用DI容器并将其用作服务定位器作为新创建对象的参数传递。从技术上讲,你可以在WinForms中做类似的事情,但它需要你将你的应用程序分成几个没有很长寿命的块(控制器)。也许值得为WinForms查看一些MVC / MVP框架,虽然我发现自己最多只能在快速google之后看到。
答案 1 :(得分:0)
问题是被引用的数据也正在通过网站进行修改,使用与EF Code First相同的DI模式,并且数据更改未反映在winforms应用程序的上下文实例中。
这是您的期望问题。
如果您的Web服务和窗口表单应用程序位于不同的进程中,则它们不会共享内存中的数据。
如果要同步其内存中的数据,只需在提交到另一个中的数据库之后在一个上下文中重新查询。这与尝试在不同SQL连接之间共享数据相同。
我可以通过每次访问时在winforms中重新创建DbContext对象来解决这个问题,但对我来说似乎更像是一个服务位置模式?
如果要重复重新创建DbContext
,可以使用抽象工厂来手动重新创建对象,但允许您将特定实现注入工厂。
这不是(必然)服务定位器模式,您必须确保手动处置DbContext
个实例。我给你一些示例代码,但不同的DI容器有完全不同的方式来完成工厂模式。
或者您可以简单地确保在Web服务端提交数据,并在WinForms应用程序端重新查询数据。