如何为实体框架4创建静态UnitOfWork?
考虑此类
public class XQueries
{
public IQueryable Query1()
{
using (XEntities context = new XEntities())
{
return something;
}
}
public IQueryable Query2()
{
using (XEntities context = new XEntities())
{
return somethingElse;
}
}
}
是否为每个 (XEntities context = new XEntities()) {...} 创建到数据库的连接?如果是这样,创建静态 UnitOfWork 类以便仅存在 1 个连接的正确方法是什么?
Considering this class
public class XQueries
{
public IQueryable Query1()
{
using (XEntities context = new XEntities())
{
return something;
}
}
public IQueryable Query2()
{
using (XEntities context = new XEntities())
{
return somethingElse;
}
}
}
Is a connection to the database created for every (XEntities context = new XEntities()) {...} ? If so what is the correct way to create a static UnitOfWork class so that only 1 connection to exist?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您无法创建静态工作单元,因为根据定义,工作单元是一个短暂的对象。由于 EF
ObjectContext
是围绕工作单元模式设计的,因此在应用程序的生命周期内拥有单个ObjectContext
实例不是一个好主意。这有几个原因。首先,
ObjectContext
类不是线程安全的。这意味着在一个用户的工作单元期间(例如在 Web 应用程序中),另一个用户可以提交他的工作单元。当它们共享相同的ObjectContext
时,这意味着在这种情况下只有一半的更改被持久化,并且更改不是事务性的。如果幸运的话,ObjectContext
会失败并抛出异常。当您不幸时,您会损坏ObjectContext
和安全,并从数据库中加载垃圾,并找出您的应用程序何时在生产中运行(当然,在测试和登台期间,一切似乎总是有效) 。其次,
ObjectContext
有一个缓存机制,其设计目的是使其寿命较短。当从数据库检索实体时,它会保留在ObjectContext
的缓存中,直到该实例被垃圾收集为止。当您使该实例长时间保持活动状态时,实体就会变得陈旧。特别是如果该特定ObjectContext
实例不是唯一写入该数据库的实例。You can't create a static unit of work, because by definition a unit of work is a short lived object. Because the EF
ObjectContext
is designed around the unit of work pattern it is a bad idea to have a singleObjectContext
instance during the life time of the application. There are several reasons for this.First of all, the
ObjectContext
class is not thread-safe. This means that during the unit of work of one user (in a web app for instance), another user can commit his unit of work. When they share the sameObjectContext
, it means that in that situation just half of the changes are persisted and changes are not transactional. When you are lucky theObjectContext
fails and throws an exception. When you are unlucky, you corrupt theObjectContext
and safe and load crap from and to your database and find out when your application is running in production (of course, during testing and staging everything always seems to work).Second, the
ObjectContext
has a caching mechanism that is designed for it to be short lived. When an entity is retrieved from the database it stays in theObjectContext
’s cache until that instance is garbage collected. When you keep that instance alive for a long period of time, entities get stale. Especially if that particularObjectContext
instance is not the only one writing to that database.实体框架仅在需要时打开连接,例如执行查询或调用 SaveChanges,然后在操作完成时关闭连接。
来自 Martin Fowler 的书《关于工作单元的企业应用程序架构模式》。
每当我为客户端使用实体框架(我承认这种情况很少见)时,ObjectContext 对象就是系统的工作单元实现。也就是说ObjectContext会在一定程度上满足上面的三个说法。使用 ObjectContext 不必过多关注绝对正确的定义,这会让事情变得更容易一些。
对 DI/IoC 和存储库模式进行一些研究,这将使您在处理问题时更加灵活。
The Entity Framework opens connections only when required, for example to execute a query or to call SaveChanges, and then closes the connection when the operation is complete.
From Martin Fowler’s book Patterns of Enterprise Application Architecture in respect to Unit Of Work.
Whenever I use Entity Framework for a clients (which I'd admit is rare) the ObjectContext object is the Unit Of Work implementation for the system. That is the ObjectContext will somewhat meet the three statements above. Rather than concentrating too much on the absolutely correct definition using the ObjectContext makes things a little easier for you.
Do some research on DI/IoC and Repository patterns this will give you more flexibility in handling your problem.