2011-04-28 98 views
3

希望你的某个人一直在那里。我需要做一些涉及多个表的数据库。我正在使用SubSonic 3 SimpleRepository更新/访问记录。现在在调用更新表之间,我打电话System.Web.Security.Roles方法来做一些查找。我正在使用单个存储库对象来完成DAO上的所有更新,但是当我的代码到达User.IsInRole("blahblah")时,它会抛出异常MSDTC is not available on the server交易和ASP.NET成员资格API

我知道这是因为SimpleRepository正在使用不同的连接而Membership API对象正在使用另一个连接。

有没有办法绕过它,或者我必须在自己的类中包装Membership API对象?

回答

1
  • 您可以配置成员/角色提供者以使用您需要的连接字符串。

  • 您可以继承这个提供者的任何一个或多个事务范围的每个方法的调用,从外部控制。

+1

与连接字符串配置它们不会使用SqlConnection对象上的任何影响,以连接到数据库。 SubSonic和Membership API正在创建不同的SqlConnection对象。 – 2011-04-29 06:12:21

+0

继承路由是方式,但我必须做额外的工作:D暂时我正在使用存储过程,但会编写一组类来包装供应商调用以供将来使用。 – TheVillageIdiot 2011-05-04 04:53:01

0

HttpContext.Current.User.IsInRole()电话RolePrincipal.IsInRole()用于通过FormsAuthentication验证的用户。内部RolePrincipal.IsInRole()调用SqlRoleProvider.GetRolesForUser(),该方法创建并销毁方法中的SqlConnection对象。

有可能是SQL Server上的其他解决方案来解决这个问题,但是从篱笆我只看到下列选项的.NET方面:

  • 实现你自己的角色提供这样就可以管理自己连接到数据库。
  • 实现您自己的IPrincipal对象,以便您可以自行管理与数据库的连接。
  • 在开始您的SubSonic交易前预先获取角色,并根据需要检查相关角色的列表。
  • 您甚至可能不需要存储角色,因为RolePrincipal.IsInRole()会在调用角色时缓存角色,并且只有在缓存为空或无效时才发送到数据库。在开始交易之前调用IsInRole()将预先填充RolePrincipal对象的缓存,这意味着在SubSonic事务中间的后续调用将从缓存中提取角色,而不是连接到数据库以获取它们。

我真的不相信最后的想法是好的,因为我确信有很多方法可能会出错。我认为最简单的解决方案是在开始SubSonic交易之前预先获取角色。

我希望有帮助。

编辑:为了完整起见,这里是RolePrincipal.IsInRole()执行情况的反射看到:

public bool IsInRole(string role) 
{ 
    if (this._Identity == null) 
    { 
     throw new ProviderException(SR.GetString("Role_Principal_not_fully_constructed")); 
    } 
    if (!this._Identity.IsAuthenticated || (role == null)) 
    { 
     return false; 
    } 
    role = role.Trim(); 
    if (!this.IsRoleListCached) 
    { 
     this._Roles.Clear(); 
     foreach (string str in Roles.Providers[this._ProviderName].GetRolesForUser(this.Identity.Name)) 
     { 
      if (this._Roles[str] == null) 
      { 
       this._Roles.Add(str, string.Empty); 
      } 
     } 
     this._IsRoleListCached = true; 
     this._CachedListChanged = true; 
    } 
    return (this._Roles[role] != null); 
}