【问题标题】:Identity change GUID to int身份将 GUID 更改为 int
【发布时间】:2014-04-28 04:02:19
【问题描述】:

如何将AspNetUser 表的PK 列从guid 数据类型更改为int? 这现在应该可以通过今天发布的最新asp.net-identity 版本来实现。

但我在任何地方都找不到这是如何完成的?

【问题讨论】:

    标签: int guid asp.net-identity


    【解决方案1】:

    默认情况下,ASP.NET 标识(使用实体框架)使用字符串作为主键,而不是 GUID,但它确实将 GUID 存储在这些字符串中。

    您需要再定义几个类,我刚刚创建了一个新项目(我使用的是 VS2013 Update 2 CTP),以下是您需要更改的身份模型:

    public class ApplicationUser : IdentityUser<int, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim>
    {
        public async Task<ClaimsIdentity> GenerateUserIdentityAsync(ApplicationUserManager manager)
        {
            // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
            var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
            // Add custom user claims here
            return userIdentity;
        }
    }
    
    public class ApplicationUserRole : IdentityUserRole<int>
    {
    }
    
    public class ApplicationUserLogin : IdentityUserLogin<int>
    {
    }
    
    public class ApplicationUserClaim : IdentityUserClaim<int>
    {
    }
    
    public class ApplicationRole : IdentityRole<int, ApplicationUserRole>
    {
    }
    
    public class ApplicatonUserStore :
        UserStore<ApplicationUser, ApplicationRole, int, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim>
    {
        public ApplicatonUserStore(ApplicationDbContext context)
            : base(context)
        {
        }
    }
    
    public class ApplicationDbContext
        : IdentityDbContext<ApplicationUser, ApplicationRole, int, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim>
    {
        public ApplicationDbContext()
            : base("DefaultConnection")
        {
        }
    }
    

    您还需要更新其他一些地方,只需遵循编译错误即可,最常见的更改是将User.Identity.GetUserId()返回的字符串转换为整数。

    另外,在回答another question(虽然我确实提出了这个问题)时,我提供了一个示例解决方案,请参阅下面的存储库:

    https://github.com/JSkimming/AspNet.Identity.EntityFramework.Multitenant

    【讨论】:

    • 我明白了.. 昨天发布的最新版asp.net-identity 还需要这个吗?我的意思是这么多自定义代码只是将int 用作PK。
    • 嗨@Quoter。是的,据我所知,我使用的是最新版本。默认 string 实现只有一个实体模型 ApplicationUser 类的原因是它派生自非泛型 IdentityUser,它本身派生自指定 stringIdentityUser<> 类/b> TKey 通用参数。 ApplicationDbContext 类也是如此。使用对象浏览器查看类,MSDN documentation 尚未更新。
    • 顺便说一下,我花了大约 10 分钟来进行必要的更改(当然我以前做过),因为一切都是使用泛型进行强类型化的,这只是遵循编译错误的问题。
    • 您是如何设法修复由 ChallengeResult() 生成的编译器错误,该错误需要 3 个字符串。最后一个期望User.Identity.GetUserId(),但我将其解析为intAuthenticationManager.GetExternalLoginInfoAsync() 也是如此。顺便说一句,您可以在AccountController() 中找到这些方法。
    • @JamesSkimming 我还查看了asp.net/identity/overview/extensibility/… 上的帖子,但不确定我是否必须向 IdentityModels 添加自定义类,如该页面上的步骤“添加使用密钥类型的自定义身份类”中所述.因为我现在正在创建项目,目前还没有创建表。我的意思是我可以修改当前类而不是添加自定义类吗?
    【解决方案2】:

    如果有人在寻找身份 3.0 指南时发现了这个:

    public class ApplicationUser : IdentityUser<int>
    {
    }
    
    public class ApplicationRole : IdentityRole<int>
    {
    }
    
    public class ApplicationDbContext: 
        IdentityDbContext<ApplicationUser, ApplicationRole, int>
    {
    }
    

    在 Startup.cs 文件中,ConfigureServices 方法:

    services.AddIdentity<ApplicationUser, ApplicationRole>()
        .AddEntityFrameworkStores<ApplicationDbContext, int>()//, int being the only difference
        .AddDefaultTokenProviders();
    

    仅此而已,无需像 2.0 那样创建管理器

    this blog post 找到这个。

    【讨论】:

      【解决方案3】:

      看看这个posthaokung 的回答

      因此,如果您想要 int id,则需要创建自己的 POCO IUser 类并在 1.0 RTM 版本中为您的自定义 IUser 类实现 IUserStore。

      这是我们没有时间支持的东西,但我现在正在考虑在 1.1 中让这个更容易(ier)。希望很快会在夜间构建中提供一些东西。

      更新了 1.1-alpha1 示例:如何获得夜间构建

      如果您更新到最新的 nightly 位,您可以尝试新的 1.1-alpha1 api,它现在应该让这更容易:下面是插入 Guids 而不是字符串的示例

      public class GuidRole : IdentityRole<Guid, GuidUserRole> { 
          public GuidRole() {
              Id = Guid.NewGuid();
          }
          public GuidRole(string name) : this() { Name = name; }
      }
      public class GuidUserRole : IdentityUserRole<Guid> { }
      public class GuidUserClaim : IdentityUserClaim<Guid> { }
      public class GuidUserLogin : IdentityUserLogin<Guid> { }
      
      public class GuidUser : IdentityUser<Guid, GuidUserLogin, GuidUserRole, GuidUserClaim> {
          public GuidUser() {
              Id = Guid.NewGuid();
          }
          public GuidUser(string name) : this() { UserName = name; }
      }
      
      private class GuidUserContext : IdentityDbContext<GuidUser, GuidRole, Guid, GuidUserLogin, GuidUserRole, GuidUserClaim> { }
      private class GuidUserStore : UserStore<GuidUser, GuidRole, Guid, GuidUserLogin, GuidUserRole, GuidUserClaim> {
          public GuidUserStore(DbContext context)
              : base(context) {
          }
      }
      private class GuidRoleStore : RoleStore<GuidRole, Guid, GuidUserRole> {
          public GuidRoleStore(DbContext context)
              : base(context) {
          }
      }
      
      [TestMethod]
      public async Task CustomUserGuidKeyTest() {
          var manager = new UserManager<GuidUser, Guid>(new GuidUserStore(new GuidUserContext()));
          GuidUser[] users = {
              new GuidUser() { UserName = "test" },
              new GuidUser() { UserName = "test1" }, 
              new GuidUser() { UserName = "test2" },
              new GuidUser() { UserName = "test3" }
              };
          foreach (var user in users) {
              UnitTestHelper.IsSuccess(await manager.CreateAsync(user));
          }
          foreach (var user in users) {
              var u = await manager.FindByIdAsync(user.Id);
              Assert.IsNotNull(u);
              Assert.AreEqual(u.UserName, user.UserName);
          }
      }
      

      【讨论】:

      • 我不明白,这是如何将它从 guid 更改为 int 的?我在这里根本看不到数据类型int。我错过了什么?
      • @Quoter 首先让我解释一下,默认实现是使用字符串,而不是 Guid,正如您在问题中指出的那样。尽管它们具有“guid 格式”,但它们实际上是作为字符串存储的。上面的这个示例向您展示了如何使用真正的 Guid 类型而不是字符串,作为如何更改为另一种数据类型的示例。更改为 int 应遵循相同的规则。
      • 几个月后阅读您的帖子,这是有道理的。 +2
      猜你喜欢
      • 1970-01-01
      • 2021-08-05
      • 1970-01-01
      • 1970-01-01
      • 2016-01-04
      • 2016-07-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多