如何共享EF的DbContext和ASPNET成员之间的连接,以避免交易上报给DTC [英] How to share a connection between EF DbContext and AspNet Membership to avoid transactions escalating to DTC

查看:166
本文介绍了如何共享EF的DbContext和ASPNET成员之间的连接,以避免交易上报给DTC的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用的EF 4.1的DbContext,数据库第一数据层的ASP.NET应用程序MVC3。我倾向于适应应用程序之前进行修改,我的数据模型的EDMX办法正常工作。该应用程序工作正常,包括元数据引用的特殊EF连接字符串。

I have an ASP.NET MVC3 application that uses an EF 4.1 DbContext, database-first data layer. The EDMX approach works fine as I tend to make changes to my data model before adapting the application to them. The application works fine with the special EF connection string that includes metadata references.

然而,有美中不足去飞。该应用程序还使用ASP.NET成员资格和需要一个标准的连接字符串的作用。我有一个同时涉及成员表和其他(EF管理)表中几个用例。由于两个独立使用的连接字符串,交易同时涉及需要DTS来处理它们。我不想去的路线,如果我能帮助它,我宁愿应用程序的所有部分简单地使用相同的连接。

However, there's one fly in the ointment. The application also uses ASP.NET membership and roles which require a standard connection string. I have several use cases that involve both the membership tables and other (EF managed) tables. As the two use separate connection strings, transactions that involve both need DTS to handle them. I don't want to go that route if I can help it, I'd rather all parts of the application simply use the same connection.

获取EF与然而,一个普通的连接字符串躲避我跑。谁能告诉我它是怎么做的吗?

Getting EF to run with a plain connection string however is eluding me. Can anyone tell me how it is done, please?

推荐答案

您有几种选择在这里。 (我知道这是很长,但请尝试读取整个事情)。这将有助于如果你可以给你需要这样的交易的实际情况。

You have several options here. (I know this is long, but please try to read the whole thing). It would help if you can give an actual scenario where you need such a transaction.

首先,你正在一个错误的假设,即如果两个EF和成员具有相同的连接字符串,它会使用一个共同的连接。这可能是真实的时候,但是没有保证。连接池尝试使用一个给定的字符串相同的连接,但如果一个连接已经在使用它会创建第二个连接(或重用池中现有的第二已连接)。因此,这种推理会惹上麻烦你在某些时候。

First, you are working on a false assumption that if both EF and Membership have the same connection string, it will use a common connection. This may be true sometimes, but is not guaranteed. Connection pooling tries to use the same connection for a given string, but if a connection is already in use it will create a second connection (or reuse an existing second connection already in the pool). So this line of reasoning will get you in trouble at some point.

一个成员资格被设计来解决问题是有一个可插拔的提供者接口,这样你就可以换出会员提供商和移动到一个不同的(如从SQL到ActiveDirectory中去),而无需修改应用程序(或有太多修改)。

One of the problems that Membership is designed to solve is to have a pluggable provider interface, so you can swap out membership providers and move to a different one (such as going from Sql to ActiveDirectory), without having to modify your application (or having to modify it much).

更紧密地集成这些功能意味着,受益远投掷。也许这是可以接受的,但你应该明白,沿着这些路径将基本紧密结合数据模型的具体成员资格提供模式。几年前,似乎并没有像它会为会员制度中的问题多年来一直没有改变......但最近,微软和其他人都不断推出新的会员系统,如具有不同的模式SimpleMembership和环球供应商

More tightly integrating these functions means throwing that benefit away. Maybe that's acceptable, but you should realize that going along these paths essentially tightly couples your data model to the specific Membership provider schemas. A few years ago, that didn't seem like it would be a problem as the membership system hadn't changed in years... but lately, MS and others have been introducing new Membership systems like SimpleMembership and Universal Providers which have different schemas.

所以,如果我们移除的成员的主要特点之一,为什么还要继续使用呢?嗯,还有从会员一些好处。主要的一个是,它提供了一个开箱即全面实施用户管理库,包括安全密码加密/哈希和类似的问题和答案认证功能。这不是小看,因为从零开始做一个安全的,无缺陷的会员制度是不平凡的(即使它会在第一次显得如此)。

So, if we're removing one of the primary features of Membership, why even continue to use it? Well, there are still some benefits from Membership. The primary one being that it provides an out of box full implementation of a user management library, including secure password encryption/hashing and features like question and answer authentication. That's not something to sneeze at, as doing a secure, bug-free membership system from scratch is not trivial (even though it would seem so at first).

于是,一种选择是实现基于现有自己的MembershipProvider(比如SqlMembershipProvider的。微软提供了源为这些)。然后,你可以简单地覆盖模式以匹配任何你想要的,但保留其他所有功能,如密码加密,什么不是。正好契合他们到自己的模式。这使得他们适合你的数据模型好多了。

So, one option is to implement your own MembershipProvider based on an existing one (like SqlMembershipProvider. Microsoft provides the source for these). Then you can simply override the schema to match whatever you want, but keep all the other features like password encryption and what not. Just fit them into your own schema. That makes them fit your data model a lot better.

不过,即使您选择使用标准成员资格提供程序,然后有一些事情可以做。

However, even if you choose to use the standard membership provider, then there are some things you can do.

首先,你可以简单的会员表映射到实体框架模型。只需将它们拖放到你的设计师或code首先添加。但是如果你这样做,你应该只使用它们为只读,你不应该创建成员表和你的表之间的外键关系。相反,只是做手工在EF查询连接(这是更多的工作,但更安全),并把它们作为单独的表。

First, you can simply map the membership tables into your Entity Framework model. Just drag and drop them onto your designer, or add them in Code First. However, if you do this, you should only use them as read-only, and you should not create foreign key relationships between the membership tables and your tables. Instead, just do manual joins in your EF query (which is more work, but safer) and treat them as stand-alone tables.

好了,哪里需要作为查询的一部分,更新或删除成员表中的数据的情况呢?坦率地说,如果你使用标准的成员表中我看到几乎没有理由这应该曾经有发生。

Ok, so what about situations where you need to update or delete data from the membership tables as part of a query? Frankly, if you're using the standard membership tables I see almost no reasons this should ever have to happen.

会员表是pretty简单,在他们如果您需要在您的应用程序的任何声明的部分非常少的实际数据。除非你正在使用的配置文件提供者,这是我永远不会做。如果你需要映射成员表,我建议创建自己的数据表,而不是使用ProfileProvider。

The Membership tables are pretty simple and have very little actual data in them you should need as part of any statements in your app. Unless you're using the Profile provider, which I never do. If you need to map the membership tables, I suggest creating your own table of data rather than using the ProfileProvider.

我看到你可能要征用事务的唯一原因是创建一个新用户的时候。然而,由于这是一个一次性事件,那么DT可能不会是这样一个可怕的事情。但是,可能并不总是提供给你一个DTC ...所以在这种情况下,你能做的最好是使用try-catch块来处理异常。

The only reason I see where you may want to enlist a transaction is when creating a new user. However, since this is a one-time event, then a DT may not be such a terrible thing. However, there may not always be a DTC available to you... so in those cases, the best you can do is use a try-catch block to deal with exceptions.

另一种方法是完全抛掉成员和创建自己的IPrincipal和IIdentity的实现和简单的写你自己的用户管理(我仍然会使用SqlManagementProvider源作为这样的基础,但是,因为它是一个很好的实现)。

The alternative is to completely throw away Membership and create your own IPrincipal and IIdentity implementations and simply write your own user management (I would still use the SqlManagementProvider source as a basis for this, however, as it's a good implementation).

然后,因为用户管理不是一个独立的子系统的一部分,你可以放心地使用它来更新和删除,而不用担心其他的子系统可能会做。

Then, since user management is not part of a separate subsystem, you can safely use it for updates and deletes without worrying about what the other subsystem might be doing.

TL; DR

如果你不能接受一个DT,则要么改变你的工作流程,改变你​​的code。与一个try-catch-finally语句的工作(虽然这不会的情况下,应用程序code保证回退突然死亡,就像一个停电),或使用自定义的IPrincipal和IIdentity的实现。

If you can't accept a DT, then either change your workflows, change your code to work with a try-catch-finally statement (though this won't guarantee rollback in case the app code dies suddenly, like a power outage), or use a custom IPrincipal and IIdentity implementation.

这篇关于如何共享EF的DbContext和ASPNET成员之间的连接,以避免交易上报给DTC的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆