【问题标题】:ASP.NET MVC 5 Storing identity users in Oracle databaseASP.NET MVC 5 在 Oracle 数据库中存储身份用户
【发布时间】:2016-04-20 20:54:00
【问题描述】:

我是开发 ASP.NET 应用程序的新手,我开始了一个新项目,我正在使用带有 ODP 和 OLAC 插件的 Oracle DB。我设置了我的连接字符串,我可以在服务器资源管理器下看到数据库。

现在我也希望将身份用户存储在我的数据库中,但我现在找不到他们的存储位置。 app_data 文件夹是空的,任何地方都没有.mdf 文件,我的连接字符串是Oracle 连接字符串;但是当我设置 IdentityDBContext 以使用我自己的连接字符串时,我收到一条错误消息 “实体类型 ApplicationUser 不是当前上下文模型的一部分。” 我使用的是数据库优先方法:

这是为我的数据库上下文自动生成的代码:

public partial class ActivoContext : DbContext
{
    public ActivoContext()
        : base("name=ActivoContext")
    {
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        throw new UnintentionalCodeFirstException();
    }
......

这是项目生成的Identity码,我只是改了连接字符串:

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext()
        : base("name=ActivoContext", throwIfV1Schema: false)
    {
    }

    public static ApplicationDbContext Create()
    {
        return new ApplicationDbContext();
    }
}

web.config 文件:

<connectionStrings>
  <add name="ActivoContext" connectionString="metadata=res://*/Activo.csdl|res://*/Activo.ssdl|res://*/Activo.msl;provider=Oracle.ManagedDataAccess.Client;provider connection string=&quot;DATA SOURCE=localhost:1521/xe;PASSWORD=activos;USER ID=ACTIVOS&quot;" providerName="System.Data.EntityClient" />
</connectionStrings>

编辑 所以我意识到问题在于使用相同的连接字符串有两个不同的上下文。正因为如此,只有一个出现,而另一个不起作用:自动生成的 db-first ActivoContext 出现,而​​ ApplicationDbContext 没有。我应该如何将这两者合并或使它们一起工作?我无法修改 DbContext 导致其自动生成...

【问题讨论】:

    标签: asp.net asp.net-mvc oracle asp.net-identity


    【解决方案1】:

    终于让 Identity 2.0 与我的 Oracle 数据库一起工作。这是我所做的:

    如果您不想对默认 IdentityUser 进行任何更改(例如,如果您可以使用 char ID 而不是 int 或 long)并且只想要现有 Oracle 架构上的表,则以下步骤有效.

    1) 在 Oracle 上创建身份表。您可以根据需要更改表名,只需确保包含 Identity 使用它所需的列。您还可以在您的应用程序中添加您可能需要的任何额外列(最初在 Devart 上找到的脚本,我将其复制到一个要点以防 URL 中断):

    要点here

    2) 如果您使用的是 EDMX 文件,则需要添加一个新的连接字符串,因为自动生成的连接字符串不起作用,您需要一个标准连接字符串。尝试遵循此模板:

    <add name="IdentityContext" connectionString="Data Source=localhost:1521/xe;PASSWORD=password;USER ID=username;" providerName="Oracle.ManagedDataAccess.Client" />
    

    3) 告诉您的 ApplicationDbContext 使用您的新 connectionString

    public ApplicationDbContext()
    : base("IdentityContext", throwIfV1Schema: false)
    {
    }
    

    4) 告诉 Identity 使用您现有的架构和表。在 IdentityModels.cs 中的 ApplicationDbContext 定义中添加此方法:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
    base.OnModelCreating(modelBuilder); // MUST go first.
    
    modelBuilder.HasDefaultSchema("YOUR_SCHEMA"); // Use uppercase!
    
    modelBuilder.Entity<ApplicationUser>().ToTable("AspNetUsers");
    modelBuilder.Entity<IdentityRole>().ToTable("AspNetRoles");
    modelBuilder.Entity<IdentityUserRole>().ToTable("AspNetUserRoles");
    modelBuilder.Entity<IdentityUserClaim>().ToTable("AspNetUserClaims");
    modelBuilder.Entity<IdentityUserLogin>().ToTable("AspNetUserLogins");
    }
    

    5) 重建,就是这样!

    【讨论】:

    • 非常感谢您为我指明正确的方向,最终使用默认 MVC 模板设置 Oracle。
    • 你好,能分享一下ApplicationDbContext的代码吗?你使用什么实体框架?
    【解决方案2】:

    您可以使用此脚本在 Oracle DB 中正确创建身份表

    `

    CREATE TABLE incapp.AspNetRoles (   
      Id VARCHAR2(128) NOT NULL,  
      Name VARCHAR2(256) NOT NULL  
     ) pctfree 20 pctused 70 tablespace INCTBL;  
     create unique index incapp.pk_aspnetroles on incapp.AspNetRoles (  
      id  
     ) pctfree 10 tablespace incidx;  
     alter table incapp.AspNetRoles add (  
      constraint pk_aspnetroles  
      primary key (id)  
     );  
     create public synonym AspNetRoles for incapp.AspNetRoles;  
     grant select,insert,update,delete on aspnetroles to webapps;  
     CREATE TABLE incapp.AspNetUserRoles (   
      UserId VARCHAR2(128) NOT NULL,  
      RoleId VARCHAR2(128) NOT NULL  
     ) pctfree 20 pctused 70 tablespace INCTBL;  
     create unique index incapp.pk_AspNetUserRoles on incapp.AspNetUserRoles (  
      UserId, RoleId  
     ) pctfree 10 tablespace incidx;  
     alter table incapp.AspNetUserRoles add (  
      constraint pk_AspNetUserRoles  
      primary key (UserId, RoleId)  
     );  
     create public synonym AspNetUserRoles for incapp.AspNetUserRoles;  
     grant select,insert,update,delete on incapp.AspNetUserRoles to webapps;  
     CREATE TABLE incapp.AspNetUsers (   
      Id VARCHAR2(128) NOT NULL,  
      Email VARCHAR2(256) NULL,  
      EmailConfirmed NUMBER(1) NOT NULL,  
      PasswordHash VARCHAR2(256) NULL,  
      SecurityStamp VARCHAR2(256) NULL,  
      PhoneNumber VARCHAR2(256) NULL,  
      PhoneNumberConfirmed NUMBER(1) NOT NULL,  
      TwoFactorEnabled NUMBER(1) NOT NULL,  
      LockoutEndDateUtc TIMESTAMP(7) NULL,  
      LockoutEnabled NUMBER(1) NOT NULL,  
      AccessFailedCount NUMBER(10) NOT NULL,  
      UserName VARCHAR2(256) NOT NULL  
     ) pctfree 20 pctused 70 tablespace INCTBL;  
     create unique index incapp.pk_AspNetUsers on incapp.AspNetUsers (  
      id  
     ) pctfree 10 tablespace incidx;  
     alter table incapp.AspNetUsers add (  
      constraint pk_AspNetUsers  
      primary key (id)  
     );  
     create public synonym AspNetUsers for incapp.AspNetUsers;  
     grant select,insert,update,delete on incapp.AspNetUsers to webapps;  
     CREATE TABLE AspNetUserClaims (   
      Id NUMBER(10) NOT NULL,  
      UserId VARCHAR2(128) NOT NULL,  
      ClaimType VARCHAR2(256) NULL,  
      ClaimValue VARCHAR2(256) NULL  
     ) pctfree 20 pctused 70 tablespace INCTBL;  
     create unique index incapp.pk_AspNetUserClaims on incapp.AspNetUserClaims (  
      id  
     ) pctfree 10 tablespace incidx;  
     alter table incapp.AspNetUserClaims add (  
      constraint pk_AspNetUserClaims  
      primary key (id)  
     );  
     create public synonym AspNetUserClaims for incapp.AspNetUserClaims;  
     grant select,insert,update,delete on incapp.AspNetUserClaims to webapps;  
     CREATE SEQUENCE incapp.AspNetUserClaims_SEQ;  
     create public synonym AspNetUserClaims_SEQ for incapp.AspNetUserClaims_SEQ;  
     CREATE OR REPLACE TRIGGER incapp.AspNetUserClaims_INS_TRG  
      BEFORE INSERT ON incapp.AspNetUserClaims  
      FOR EACH ROW  
     BEGIN  
      :NEW.Id := AspNetUserClaims_SEQ.NEXTVAL;  
     END;  
     /  
     CREATE TABLE incapp.AspNetUserLogins (   
      LoginProvider VARCHAR2(128) NOT NULL,  
      ProviderKey VARCHAR2(128) NOT NULL,  
      UserId VARCHAR2(128) NOT NULL  
     ) pctfree 20 pctused 70 tablespace INCTBL;  
     create unique index incapp.pk_AspNetUserLogins on incapp.AspNetUserLogins (  
      LoginProvider, ProviderKey, UserId  
     ) pctfree 10 tablespace incidx;  
     alter table incapp.AspNetUserLogins add (  
      constraint pk_AspNetUserLogins  
      primary key (LoginProvider, ProviderKey, UserId)  
     );  
     create public synonym AspNetUserLogins for incapp.AspNetUserLogins;  
     grant select,insert,update,delete on incapp.AspNetUserLogins to webapps;  
     create unique index incapp.RoleNameIndex on incapp.AspNetRoles (  
      name  
     ) pctfree 10 tablespace incidx;  
     alter table incapp.AspNetRoles add (  
      constraint uq_RoleNameIndex  
      unique (name)  
     );  
     create index incapp.IX_AspNetUserRoles_UserId on incapp.AspNetUserRoles (  
      UserId  
     ) pctfree 10 tablespace incidx;  
     create index incapp.IX_AspNetUserRoles_RoleId on incapp.AspNetUserRoles (  
      RoleId  
     ) pctfree 10 tablespace incidx;  
     create unique index incapp.UserNameIndex on incapp.AspNetUsers (  
      UserName  
     ) pctfree 10 tablespace incidx;  
     create index incapp.IX_AspNetUserClaims_UserId on incapp.AspNetUserClaims (  
      UserId  
     ) pctfree 10 tablespace incidx;  
     create index incapp.IX_AspNetUserLogins_UserId on incapp.AspNetUserLogins (  
      UserId  
     ) pctfree 10 tablespace incidx;  
     ALTER TABLE incapp.AspNetUserRoles  
      ADD CONSTRAINT FK_UserRoles_Roles FOREIGN KEY (RoleId) REFERENCES incapp.AspNetRoles (Id)  
      ON DELETE CASCADE;  
     ALTER TABLE incapp.AspNetUserRoles  
      ADD CONSTRAINT FK_UserRoles_Users FOREIGN KEY (UserId) REFERENCES incapp.AspNetUsers (Id)  
      ON DELETE CASCADE;  
     ALTER TABLE incapp.AspNetUserClaims  
      ADD CONSTRAINT FK_UserClaims_Users FOREIGN KEY (UserId) REFERENCES incapp.AspNetUsers (Id)  
      ON DELETE CASCADE;  
     ALTER TABLE incapp.AspNetUserLogins  
      ADD CONSTRAINT FK_UserLogins_Users FOREIGN KEY (UserId) REFERENCES incapp.AspNetUsers (Id)  
      ON DELETE CASCADE;
    

    `

    如下所示修改 ConnectionString

    <add name="DBContext" connectionString="Data Source=AAAA:1521/AA;PASSWORD=AAAA;USER ID=AAAA;" providerName="Oracle.ManagedDataAccess.Client" />
    

    然后像这样修改你的 OnModelCreating 方法

    `

    protected override void OnModelCreating(DbModelBuilder modelBuilder)  
         {  
           base.OnModelCreating(modelBuilder);  
           modelBuilder.HasDefaultSchema("AAAAA");
           modelBuilder.Entity<ApplicationUser>()  
           .ToTable("ASPNETUSERS").Property(p => p.UserName).HasColumnName("USERNAME");  
           modelBuilder.Entity<ApplicationUser>()  
           .ToTable("ASPNETUSERS").Property(p => p.AccessFailedCount).HasColumnName("ACCESSFAILEDCOUNT");  
           modelBuilder.Entity<ApplicationUser>()  
           .ToTable("ASPNETUSERS").Property(p => p.LockoutEnabled).HasColumnName("LOCKOUTENABLED");  
           modelBuilder.Entity<ApplicationUser>()  
           .ToTable("ASPNETUSERS").Property(p => p.LockoutEndDateUtc).HasColumnName("LOCKOUTENDDATEUTC");  
           modelBuilder.Entity<ApplicationUser>()  
           .ToTable("ASPNETUSERS").Property(p => p.TwoFactorEnabled).HasColumnName("TWOFACTORENABLED");  
           modelBuilder.Entity<ApplicationUser>()  
           .ToTable("ASPNETUSERS").Property(p => p.PhoneNumberConfirmed).HasColumnName("PHONENUMBERCONFIRMED");  
           modelBuilder.Entity<ApplicationUser>()  
           .ToTable("ASPNETUSERS").Property(p => p.PhoneNumber).HasColumnName("PHONENUMBER");  
           modelBuilder.Entity<ApplicationUser>()  
           .ToTable("ASPNETUSERS").Property(p => p.SecurityStamp).HasColumnName("SECURITYSTAMP");  
           modelBuilder.Entity<ApplicationUser>()  
           .ToTable("ASPNETUSERS").Property(p => p.PasswordHash).HasColumnName("PASSWORDHASH");  
           modelBuilder.Entity<ApplicationUser>()  
           .ToTable("ASPNETUSERS").Property(p => p.EmailConfirmed).HasColumnName("EMAILCONFIRMED");  
           modelBuilder.Entity<ApplicationUser>()  
           .ToTable("ASPNETUSERS").Property(p => p.Email).HasColumnName("EMAIL");  
           modelBuilder.Entity<ApplicationUser>()  
           .ToTable("ASPNETUSERS").Property(p => p.Id).HasColumnName("ID");  
           modelBuilder.Entity<IdentityUserRole>()  
           .ToTable("ASPNETUSERROLES").Property(p => p.RoleId).HasColumnName("ROLEID");  
           modelBuilder.Entity<IdentityUserRole>()  
           .ToTable("ASPNETUSERROLES").Property(p => p.UserId).HasColumnName("USERID");  
           modelBuilder.Entity<IdentityUserLogin>()  
           .ToTable("ASPNETUSERLOGINS").Property(p => p.UserId).HasColumnName("USERID");  
           modelBuilder.Entity<IdentityUserLogin>()  
           .ToTable("ASPNETUSERLOGINS").Property(p => p.ProviderKey).HasColumnName("PROVIDERKEY");  
           modelBuilder.Entity<IdentityUserLogin>()  
           .ToTable("ASPNETUSERLOGINS").Property(p => p.LoginProvider).HasColumnName("LOGINPROVIDER");  
           modelBuilder.Entity<IdentityUserClaim>()  
           .ToTable("ASPNETUSERCLAIMS").Property(p => p.Id).HasColumnName("ID");  
           modelBuilder.Entity<IdentityUserClaim>()  
           .ToTable("ASPNETUSERCLAIMS").Property(p => p.UserId).HasColumnName("USERID");  
           modelBuilder.Entity<IdentityUserClaim>()  
           .ToTable("ASPNETUSERCLAIMS").Property(p => p.ClaimType).HasColumnName("CLAIMTYPE");  
           modelBuilder.Entity<IdentityUserClaim>()  
           .ToTable("ASPNETUSERCLAIMS").Property(p => p.ClaimValue).HasColumnName("CLAIMVALUE");  
           modelBuilder.Entity<IdentityRole>()  
           .ToTable("ASPNETROLES").Property(p => p.Id).HasColumnName("ID");  
           modelBuilder.Entity<IdentityRole>()  
           .ToTable("ASPNETROLES").Property(p => p.Name).HasColumnName("NAME");  
         } 
    

    `

    这在我的项目中运行良好。

    您可以在这里找到一些有趣的点。 (ASP.NET MVC、EF 与 NgGet Oracle 12.2.1..)

    ASP.NET Identity With Oracle Database

    【讨论】:

    • 请不要只依赖链接你的答案。链接可能会停止工作,帖子变得毫无用处。请尝试在您的帖子中解释更多。
    • @Ondrej K。谢谢你的提示。我会更新我的答案。让我知道答案有什么问题。
    猜你喜欢
    • 2016-04-04
    • 2017-06-16
    • 1970-01-01
    • 2014-04-30
    • 1970-01-01
    • 2020-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多