然而,美中不足的有一只苍蝇.该应用程序还使用需要标准连接字符串的ASP.NET成员资格和角色.我有几个涉及成员资格表和其他(EF托管)表的用例.由于两者使用单独的连接字符串,涉及两者的事务都需要DTS来处理它们.如果我可以帮助它,我不想走那条路,我宁愿应用程序的所有部分只使用相同的连接.
让EF使用普通的连接字符串运行但是让我不知所措.谁能告诉我它是怎么做的,拜托?
解决方法
首先,您正在假设如果EF和Membership都具有相同的连接字符串,它将使用公共连接.有时这可能是真的,但不能保证.连接池尝试对给定的字符串使用相同的连接,但是如果连接已在使用中,它将创建第二个连接(或重用池中已有的现有第二个连接).所以这一推理会让你在某些方面遇到麻烦.
Membership旨在解决的一个问题是拥有一个可插拔的提供程序接口,因此您可以更换成员资格提供程序并转移到另一个(例如从sql转到ActiveDirectory),而无需修改您的应用程序(或具有修改它).
更紧密地整合这些功能意味着抛弃这些好处.也许这是可以接受的,但是您应该意识到,沿着这些路径将您的数据模型与特定的成员资格提供者模式紧密地结合在一起.几年前,这似乎不是一个问题,因为会员制度多年来没有改变……但最近,MS和其他人一直在推出新的会员制度,如SimpleMembership和Universal Providers,它们有不同的模式.
那么,如果我们要删除会员资格的一个主要功能,为什么还要继续使用呢?好吧,会员资格还有一些好处.主要的一点是它提供了用户管理库的开箱即用的完整实现,包括安全密码加密/散列以及问答验证等功能.这不是打喷嚏的事情,因为从头开始做一个安全,无错误的会员系统并不是微不足道的(尽管起初看起来似乎如此).
因此,一种选择是基于现有的MembershipProvider实现您自己的MembershipProvider(如sqlMembershipProvider.Microsoft为这些提供了源代码).然后,您可以简单地覆盖架构以匹配您想要的任何内容,但保留所有其他功能,如密码加密和其他功能.只需将它们放入您自己的架构中.这使它们更适合您的数据模型.
但是,即使您选择使用标准会员提供商,也可以执行一些操作.
首先,您可以简单地将成员资格表映射到您的Entity Framework模型中.只需将它们拖放到设计器上,或将它们添加到Code First中即可.但是,如果执行此操作,则只应将它们用作只读,并且不应在成员资格表和表之间创建外键关系.相反,只需在EF查询中进行手动连接(这是更多工作,但更安全)并将它们视为独立表.
那么,作为查询的一部分,您需要更新或删除成员资格表中的数据的情况呢?坦率地说,如果您使用的是标准会员表,我几乎看不出应该发生这种情况的原因.
Membership表格非常简单,并且您应该在应用程序中的任何语句中包含非常少的实际数据.除非您使用的是配置文件提供程序,否则我从不这样做.如果您需要映射成员资格表,我建议您创建自己的数据表而不是使用ProfileProvider.
我看到您可能想要在何处登记交易的唯一原因是创建新用户时.但是,由于这是一次性事件,因此DT可能不是那么可怕的事情.但是,可能并不总是有可用的DTC …因此在这些情况下,您可以做的最好的事情是使用try-catch块来处理异常.
另一种方法是完全抛弃Membership并创建自己的IPrincipal和IIdentity实现,并简单地编写自己的用户管理(我仍然会使用sqlManagementProvider源作为基础,但是,因为它是一个很好的实现).
然后,由于用户管理不是单独子系统的一部分,因此您可以安全地将其用于更新和删除,而无需担心其他子系统可能正在执行的操作.
TL; DR
如果你不能接受DT,那么要么改变你的工作流程,要改变你的代码以使用try-catch-finally语句(虽然这不能保证在应用程序代码突然死亡的情况下回滚,如停电),或使用自定义IPrincipal和IIdentity实现.