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

发布于 2024-09-12 17:04:42 字数 470 浏览 9 评论 0原文

考虑此类

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

肤浅与狂妄 2024-09-19 17:04:42

您无法创建静态工作单元,因为根据定义,工作单元是一个短暂的对象。由于 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 single ObjectContext 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 same ObjectContext, it means that in that situation just half of the changes are persisted and changes are not transactional. When you are lucky the ObjectContext fails and throws an exception. When you are unlucky, you corrupt the ObjectContext 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 the ObjectContext’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 particular ObjectContext instance is not the only one writing to that database.

甜心小果奶 2024-09-19 17:04:42

实体框架仅在需要时打开连接,例如执行查询或调用 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.

When you're pulling data in and out of
a database, it's important to keep
track of what you've changed;
otherwise, that data won't be written
back into the database. Similarly you
have to insert new objects you create
and remove any objects you delete.

You can change the database with each
change to your object model, but this
can lead to lots of very small
database calls, which ends up being
very slow. Furthermore it requires you
to have a transaction open for the
whole interaction, which is
impractical if you have a business
transaction that spans multiple
requests. The situation is even worse
if you need to keep track of the
objects you've read so you can avoid
inconsistent reads.

A Unit of Work keeps track of
everything you do during a business
transaction that can affect the
database. When you're done, it figures
out everything that needs to be done
to alter the database as a result of
your 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文