我需要将ASP.NET Web API添加到已有活动用户数据库的系统中。
根据我使用asp.net内置的默认Identity的经验,它通常使用代码优先方法从头开始创建表。这显然不是我想要的方法。
我如何将Identity Model指向我当前的数据库,而不是创建一个新数据库?
我似乎无法找到一个体面的教程或如何在线?
我假设我必须在身份包中的某些位置实现一个接口,以便我提供正常操作所需的最小字段。
我想为用户角色和用户身份执行此操作。
我首先将当前数据库导入代码吗?
{编辑}
这是我的表格的链接: ERD
答案 0 :(得分:4)
可以通过覆盖OnModelCreating事件来映射ASP.NET Identity对象和属性。这看起来像 -
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
var user = modelBuilder.Entity<IdentityUser>().HasKey(u => u.Id).ToTable("User", "Users"); //Specify our our own table names instead of the defaults
user.Property(iu => iu.Id).HasColumnName("Id");
user.Property(iu => iu.UserName).HasColumnName("UserName");
user.Property(iu => iu.Email).HasColumnName("EmailAddress").HasMaxLength(254).IsRequired();
user.Property(iu => iu.IsConfirmed).HasColumnName("EmailConfirmed");
user.Property(iu => iu.PasswordHash).HasColumnName("PasswordHash");
user.Property(iu => iu.SecurityStamp).HasColumnName("SecurityStamp");
user.HasMany(u => u.Roles).WithRequired().HasForeignKey(ur => ur.UserId);
user.HasMany(u => u.Claims).WithRequired().HasForeignKey(uc => uc.UserId);
user.HasMany(u => u.Logins).WithRequired().HasForeignKey(ul => ul.UserId);
user.Property(u => u.UserName).IsRequired();
...
对每个实体使用“ToTable”,为每个属性使用“HasColumnName”,您应该能够映射到自己的模式。
显而易见的问题是,这只会允许您更改列名和表名,而不是列类型。
您可以扩展IdentityUser类以添加与架构中其他数据库列匹配的新属性,并且可以更改用户和角色的主键类型(请参阅http://aspnet.codeplex.com/SourceControl/latest#Samples/Identity/ChangePK/readme.txt),但核心列类型和信息需要相同。这很可能是密码哈希列的问题,在ASP.NET身份的情况下,它实际上包含哈希和盐。
如果您有现有的用户凭据,则可能需要对其进行翻译 - 从http://www.asp.net/identity/overview/migrations/migrating-an-existing-website-from-sql-membership-to-aspnet-identity并使用https://aspnet.codeplex.com/SourceControl/latest#Samples/Identity/SQLMembership-Identity-OWIN/Migrations.sql处的脚本
提供了从SQL成员身份执行此操作的过程。该过程的关键点是 -
加密并存储应用程序用户的密码 在数据库中。 SQL成员资格中使用的加密算法是 与新身份系统中的不同。重用旧的 我们需要在旧用户登录时有选择地解密密码的密码 在使用加密时使用SQL成员资格算法 新用户身份识别算法。
可能也可以在使用以前的成员资格算法成功登录后暂时保留密码,然后使用明文字符串将密码添加到使用ASP的新ASP.NET身份密码列.NET Identity散列和用户管理器机制 - 但在这种情况下,您应该非常小心地传递纯文本凭据。在成功迁移之后,如果将来发生破坏,您还应该销毁先前系统中的(更弱的哈希)凭证(如果在迁移到明显更强大的哈希ASP.NET Identity列之后未更改凭证)。 p>
答案 1 :(得分:3)
IdentityDbContext
与正常DbContext
没有什么不同。如果您不希望它创建表,那么您只需将其视为数据库优先(是的,您可能会混淆地拥有数据库优先的代码优先项目)。
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("ConnectionStringName")
{
Database.SetInitializer<ApplicationDbContext>(null);
}
}
当然,您必须将此上下文与您进行迁移的应用程序上下文分开,但现在它将不再尝试创建数据库或生成表。
答案 2 :(得分:0)
另一个选项可能是子类Microsoft.AspNet.Identity.EntityFramework.IdentityDbContext<Models.ApplicationUser>
,这显然只适用于你还没有继承另一个DbContext派生类型的时候。
例如:
public class MyDbContext : IdentityDbContext<ApplicationUser>, IMyDbContext
{
public IDbSet<MyOtherEntity> OtherEntities { get; set; }
public MyDbContext() : base("MyDb", false)
{
Database.SetInitializer<MyDbContext>(null);
}
public static DbContext Create()
{
return new MyDbContext();
}
}
您需要修改 Startup.Auth.cs 并更新app.CreatePerOwinContext
调用,而不是参考新DbContext类型的Create()
方法(或任何DI-您已经在已建立的成熟产品中使用的基于分配器。)请记住,您在此处提供的方法返回的类型是用于未来Owin上下文Get()
调用的类型。
因此,您还需要编辑 IdentityConfig.cs ,而不是引用MyDbContext
类型(而不是ApplicationDbContext
)。否则此方法将失败。如果在编辑后,您在此处获得空引用异常,则表示您未正确编辑 Startup.Auth.cs (请参阅上一段。)
您也可以明确评论出位于 IdentityModels.cs 中的默认支架ApplicationDbContext
,以便其他开发人员在将来不会感到困惑,它也应该有助于您识别任何挥之不去的引用(不应该有任何。)
对于大多数常见情况,上述内容应该足够了,如果您现有的数据库架构与默认生成的架构不同,您可以覆盖{@ 1}},如@pwdst接受的答案中所述(除了详情如上。)