如何为实体框架4创建静态UnitOfWork?

时间:2010-08-01 11:59:12

标签: entity-framework entity-framework-4 unitofworkapplication

考虑这个课程

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个连接存在?

2 个答案:

答案 0 :(得分:1)

您无法创建静态工作单元,因为根据定义,工作单元是一个短暂的对象。因为EF ObjectContext是围绕工作单元设计的,所以在应用程序的生命周期内拥有一个ObjectContext实例是个坏主意。有几个原因。

首先,ObjectContext类不是线程安全的。这意味着在一个用户的工作单元(例如,在Web应用程序中)中,另一个用户可以提交他的工作单元。当它们共享相同的ObjectContext时,这意味着在这种情况下,只有一半的更改是持久的,更改不是事务性的。幸运的是ObjectContext失败并抛出异常。当你运气不好时,你会破坏ObjectContext安全并从数据库中加载垃圾并找出你的应用程序在生产中运行的时间(当然,在测试和暂存期间,一切似乎都能正常工作)。

其次,ObjectContext有一个缓存机制,旨在使其短暂存在。从数据库中检索实体时,它将保留在ObjectContext的缓存中,直到该实例被垃圾收集。当您将该实例保持长时间存活时,实体会变得陈旧。特别是如果该特定ObjectContext实例不是唯一写入该数据库的实例。

答案 1 :(得分:0)

实体框架仅在需要时打开连接,例如执行查询或调用SaveChanges,然后在操作完成时关闭连接。

来自Martin Fowler的关于工作单元的企业应用程序架构模式。

  

当您将数据拉入和拉出时   一个数据库,重要的是要保持   跟踪你改变了什么;   否则,将不会写入该数据   回到数据库。同样的你   必须插入您创建的新对象   并删除您删除的任何对象。

     

您可以使用每个更改数据库   更改为您的对象模型,但这   可以导致很多非常小的   数据库调用,最终成为   非常慢。此外,它需要你   让交易开放   整个互动,这是   如果你有生意,这是不切实际的   跨越多个的交易   要求。情况更糟   如果你需要跟踪   你读过的对象,你可以避免   读数不一致。

     

工作单元跟踪   你在商业中所做的一切   可能影响的交易   数据库。当你完成后,它就会成功   完成所有需要完成的事情   由于改变了数据库   你的工作。

每当我为客户端使用Entity Framework时(我承认很少见),ObjectContext对象就是系统的Unit Of Work实现。那就是ObjectContext会在某种程度上符合上面的三个陈述。使用ObjectContext而不是过分关注绝对正确的定义,而不是让事情变得更容易。

对DI / IoC和Repository模式进行一些研究,这将为您提供更灵活的处理问题。