考虑到这门课
public class XQueries
{
public IQueryable Query1()
{
using (XEntities context = new XEntities())
{
return something;
}
}
public IQueryable Query2()
{
using (XEntities context = new XEntities())
{
return somethingElse;
}
}
}是否为每个(新上下文=XEntities XEntities()) {...}创建到数据库的连接?如果是这样,那么创建一个静态UnitOfWork类以便只存在一个连接的正确方法是什么?
发布于 2010-08-01 21:08:40
您不能创建静态工作单元,因为根据定义,工作单元是一个短暂的对象。因为EF ObjectContext是围绕工作单元模式设计的,所以在应用程序的生命周期中只有一个ObjectContext实例不是一个好主意。这有几个原因。
首先,ObjectContext类不是线程安全的。这意味着在一个用户的工作单元期间(例如在web应用程序中),另一个用户可以提交他的工作单元。当它们共享相同的ObjectContext时,这意味着在这种情况下,只有一半的更改是持久化的,并且更改不是事务性的。幸运的是,ObjectContext会失败并抛出异常。当您不走运时,您会破坏ObjectContext和safe,并将垃圾加载到数据库和数据库中,并找出应用程序何时在生产环境中运行(当然,在测试和升级期间,一切似乎都正常)。
其次,ObjectContext有一个专门为其设计的短期缓存机制。当从数据库中检索到一个实体时,它会一直留在ObjectContext的缓存中,直到该实例被垃圾回收。当您长时间保持该实例的活动状态时,实体就会变得陈旧。特别是如果该特定的ObjectContext实例不是唯一写入该数据库的实例。
发布于 2010-08-01 20:25:55
实体框架仅在需要时打开连接,例如执行查询或调用SaveChanges,然后在操作完成时关闭连接。
摘自Martin Fowler的关于工作单元的企业应用程序架构模式一书。
当您将数据拉入和拉出数据库时,跟踪您所做的更改非常重要;否则,这些数据将不会被写回数据库。同样,您必须插入您创建的新对象,并删除您删除的任何对象。
您可以随着对象模型的每次更改而更改数据库,但这可能会导致大量非常小的数据库调用,最终会非常慢。此外,它要求您为整个交互打开一个事务,如果您有一个跨越多个请求的业务事务,这是不切实际的。如果您需要跟踪已读取的对象,以避免不一致的读取,则情况会更糟。
工作单元跟踪您在业务事务期间所做的可能影响数据库的所有操作。完成后,它会根据您的工作结果找出更改数据库所需执行的所有操作。
每当我为客户端使用实体框架(我承认这种情况很少)时,ObjectContext对象就是系统的工作单元实现。也就是说,ObjectContext将在某种程度上满足上述三个声明。与其过多地关注绝对正确的定义,不如使用ObjectContext让事情变得更简单。
对DI/IoC和Repository模式进行一些研究这将使您在处理问题时具有更大的灵活性。
https://stackoverflow.com/questions/3381923
复制相似问题