【问题标题】:ApplicationUser DbContext Merge with My DBcontextApplicationUser DbContext 与我的 DBcontext 合并
【发布时间】:2015-06-25 12:05:24
【问题描述】:

我现在意识到,我有一个应用程序愚蠢地有两个单独的 DBcontexts,它们需要合并以允许应用程序实体和 ApplicationUser 实体之间的关系。

随着应用程序的开发,我相信在其他类中对 applicationUser 的引用已经为我的 DBcontext 上的 ApplicationUser 实体创建了表,而在不同的连接字符串和上下文中存在 AspUserIdentity 等表。

我试图删除原始上下文并合并两个上下文,但是在尝试创建迁移时,它想将我当前上下文中的所有现有 ApplicationUser 表重命名为 AspUserIdentity 等(见下文)

我怎样才能成功合并上下文或有其他解决方案?

我不确定要发布什么,但我会尝试发布我认为相关的内容,如果有人需要更多信息,请随时提出要求。

这是尝试合并后的所有代码。 (使用该问题的答案之一中的指南:Merge MyDbContext to Asp.net IdentityDbContext

我的上下文有以下表格: 应用程序用户 身份角色 身份用户声明 身份用户登录 身份用户角色

原始上下文具有以下表,迁移正在尝试重命名上述表以匹配这些表: AspNet 角色 AspNetUserClaims AspNetUserLogins AspNetUserRoles AspNet 用户

我的上下文:(注释的 Modelbuilder 语句导致多重性错误)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

using System.Data.Entity;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Configuration;
using System.Web.Mvc;
using Microsoft.AspNet.Identity.EntityFramework;
using System.Data.Entity.ModelConfiguration.Conventions;
using eCommSite.Models;
using System.Data.Entity.Infrastructure;

namespace eCommSite.Areas.Admin.Models
{
    public class TheDBContext : IdentityDbContext 
    {

        public TheDBContext()
                : base(ConfigurationManager.ConnectionStrings["DataDBString"].ConnectionString)
            {
                var objectContext = (this as IObjectContextAdapter).ObjectContext;

                // Sets the command timeout for all the commands
                objectContext.CommandTimeout = 360;
            }
        public DbSet<ProductBase> ProductBases { get; set; }
        public DbSet<Address> Addresses { get; set; }
        public DbSet<PromotionImage> PromotionImages { get; set; }
        public DbSet<Image> Images { get; set; }
        public DbSet<ImageCollection> ImageCollections { get; set; }
        public DbSet<Order> Orders { get; set; }
        public DbSet<OrderLine> OrderLines { get; set; }
        public DbSet<ProductOption> ProductOptions { get; set; }
        public DbSet<ProductOptionType> ProductOptionTypes { get; set; }
        public DbSet<ProductType> ProductTypes { get; set; }
        public DbSet<FilterValueEntry> FilterValueEntries { get; set; }
        public DbSet<FilterType> FilterTypesDB { get; set; }
        public DbSet<CardBaseSummary> CardBaseSummarys { get; set; }
        public DbSet<ProductBaseSummary> ProductBaseSummaries { get; set; }
        public DbSet<Category> Categories { get; set; }
        public DbSet<Brand> Brands { get; set; }
        public DbSet<MMHPriceEntry> MMHPriceEntries { get; set; }
        public DbSet<Legality> Legalities { get; set; }
        public DbSet<ForeignName> ForeignNames { get; set; }
        public DbSet<SKUStockQuantity> SKUStockQuantities { get; set; }
        public DbSet<Location> Locations { get; set; }
        public DbSet<Cart> Carts { get; set; }
        public DbSet<StockCollection> StockCollections { get; set; }

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

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);

            modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
            modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();


          //  modelBuilder.Entity<IdentityUserLogin>().HasKey<string>(l => l.UserId);
          //  modelBuilder.Entity<IdentityRole>().HasKey<string>(r => r.Id);
         //   modelBuilder.Entity<IdentityUserRole>().HasKey(r => new { r.RoleId, r.UserId });

        }

        public System.Data.Entity.DbSet<eCommSite.Areas.Admin.Models.ApplicationUser> ApplicationUsers { get; set; }

        public System.Data.Entity.DbSet<eCommSite.Areas.Admin.Models.ProductRelation> ProductRelations { get; set; }

        public System.Data.Entity.DbSet<eCommSite.Areas.Admin.Models.MTG_Cards> MTG_Cards { get; set; }

        public System.Data.Entity.DbSet<eCommSite.Areas.Admin.Models.MTG_Set> MTG_Set { get; set; }

        public System.Data.Entity.DbSet<eCommSite.Areas.Admin.Models.ProductOptionValue> ProductOptionValues { get; set; }

        public System.Data.Entity.DbSet<eCommSite.Areas.Admin.Models.SKU> SKUs { get; set; }

        public System.Data.Entity.DbSet<eCommSite.Areas.Admin.Models.MMHsetToJsonSetReference> MMHsetToJsonSetReferences { get; set; }

    }
}

迁移:

namespace eCommSite.Migrations
{
    using System;
    using System.Data.Entity.Migrations;

    public partial class MergeMigration : DbMigration
    {
        public override void Up()
        {
            RenameTable(name: "dbo.ApplicationUsers", newName: "AspNetUsers");
            RenameTable(name: "dbo.IdentityUserClaims", newName: "AspNetUserClaims");
            RenameTable(name: "dbo.IdentityUserLogins", newName: "AspNetUserLogins");
            RenameTable(name: "dbo.IdentityUserRoles", newName: "AspNetUserRoles");
            RenameTable(name: "dbo.IdentityRoles", newName: "AspNetRoles");
            DropIndex("dbo.AspNetUserClaims", new[] { "ApplicationUser_Id" });
            DropIndex("dbo.AspNetUserLogins", new[] { "ApplicationUser_Id" });
            DropIndex("dbo.AspNetUserRoles", new[] { "ApplicationUser_Id" });
            DropIndex("dbo.AspNetUserRoles", new[] { "IdentityRole_Id" });
            DropColumn("dbo.AspNetUserClaims", "UserId");
            DropColumn("dbo.AspNetUserLogins", "UserId");
            DropColumn("dbo.AspNetUserRoles", "UserId");
            DropColumn("dbo.AspNetUserRoles", "RoleId");
            RenameColumn(table: "dbo.AspNetUserClaims", name: "ApplicationUser_Id", newName: "UserId");
            RenameColumn(table: "dbo.AspNetUserLogins", name: "ApplicationUser_Id", newName: "UserId");
            RenameColumn(table: "dbo.AspNetUserRoles", name: "ApplicationUser_Id", newName: "UserId");
            RenameColumn(table: "dbo.AspNetUserRoles", name: "IdentityRole_Id", newName: "RoleId");
            DropPrimaryKey("dbo.AspNetUserLogins");
            DropPrimaryKey("dbo.AspNetUserRoles");
            AddColumn("dbo.AspNetUsers", "Discriminator", c => c.String(nullable: false, maxLength: 128));
            AlterColumn("dbo.AspNetUsers", "Newsletter", c => c.Boolean());
            AlterColumn("dbo.AspNetUsers", "RewardPoints", c => c.Int());
            AlterColumn("dbo.AspNetUsers", "BasketId", c => c.Int());
            AlterColumn("dbo.AspNetUsers", "BuylistBasketId", c => c.Int());
            AlterColumn("dbo.AspNetUsers", "StoreCredit", c => c.Double());
            AlterColumn("dbo.AspNetUsers", "Email", c => c.String(maxLength: 256));
            AlterColumn("dbo.AspNetUsers", "UserName", c => c.String(nullable: false, maxLength: 256));
            AlterColumn("dbo.AspNetUserClaims", "UserId", c => c.String(nullable: false, maxLength: 128));
            AlterColumn("dbo.AspNetUserClaims", "UserId", c => c.String(nullable: false, maxLength: 128));
            AlterColumn("dbo.AspNetUserLogins", "LoginProvider", c => c.String(nullable: false, maxLength: 128));
            AlterColumn("dbo.AspNetUserLogins", "ProviderKey", c => c.String(nullable: false, maxLength: 128));
            AlterColumn("dbo.AspNetUserLogins", "UserId", c => c.String(nullable: false, maxLength: 128));
            AlterColumn("dbo.AspNetUserRoles", "UserId", c => c.String(nullable: false, maxLength: 128));
            AlterColumn("dbo.AspNetUserRoles", "RoleId", c => c.String(nullable: false, maxLength: 128));
            AlterColumn("dbo.AspNetRoles", "Name", c => c.String(nullable: false, maxLength: 256));
            AddPrimaryKey("dbo.AspNetUserLogins", new[] { "LoginProvider", "ProviderKey", "UserId" });
            AddPrimaryKey("dbo.AspNetUserRoles", new[] { "UserId", "RoleId" });
            CreateIndex("dbo.AspNetUsers", "UserName", unique: true, name: "UserNameIndex");
            CreateIndex("dbo.AspNetUserClaims", "UserId");
            CreateIndex("dbo.AspNetUserLogins", "UserId");
            CreateIndex("dbo.AspNetUserRoles", "UserId");
            CreateIndex("dbo.AspNetUserRoles", "RoleId");
            CreateIndex("dbo.AspNetRoles", "Name", unique: true, name: "RoleNameIndex");
        }

        public override void Down()
        {
            DropIndex("dbo.AspNetRoles", "RoleNameIndex");
            DropIndex("dbo.AspNetUserRoles", new[] { "RoleId" });
            DropIndex("dbo.AspNetUserRoles", new[] { "UserId" });
            DropIndex("dbo.AspNetUserLogins", new[] { "UserId" });
            DropIndex("dbo.AspNetUserClaims", new[] { "UserId" });
            DropIndex("dbo.AspNetUsers", "UserNameIndex");
            DropPrimaryKey("dbo.AspNetUserRoles");
            DropPrimaryKey("dbo.AspNetUserLogins");
            AlterColumn("dbo.AspNetRoles", "Name", c => c.String());
            AlterColumn("dbo.AspNetUserRoles", "RoleId", c => c.String(maxLength: 128));
            AlterColumn("dbo.AspNetUserRoles", "UserId", c => c.String(maxLength: 128));
            AlterColumn("dbo.AspNetUserLogins", "UserId", c => c.String(maxLength: 128));
            AlterColumn("dbo.AspNetUserLogins", "ProviderKey", c => c.String());
            AlterColumn("dbo.AspNetUserLogins", "LoginProvider", c => c.String());
            AlterColumn("dbo.AspNetUserClaims", "UserId", c => c.String(maxLength: 128));
            AlterColumn("dbo.AspNetUserClaims", "UserId", c => c.String());
            AlterColumn("dbo.AspNetUsers", "UserName", c => c.String());
            AlterColumn("dbo.AspNetUsers", "Email", c => c.String());
            AlterColumn("dbo.AspNetUsers", "StoreCredit", c => c.Double(nullable: false));
            AlterColumn("dbo.AspNetUsers", "BuylistBasketId", c => c.Int(nullable: false));
            AlterColumn("dbo.AspNetUsers", "BasketId", c => c.Int(nullable: false));
            AlterColumn("dbo.AspNetUsers", "RewardPoints", c => c.Int(nullable: false));
            AlterColumn("dbo.AspNetUsers", "Newsletter", c => c.Boolean(nullable: false));
            DropColumn("dbo.AspNetUsers", "Discriminator");
            AddPrimaryKey("dbo.AspNetUserRoles", new[] { "RoleId", "UserId" });
            AddPrimaryKey("dbo.AspNetUserLogins", "UserId");
            RenameColumn(table: "dbo.AspNetUserRoles", name: "RoleId", newName: "IdentityRole_Id");
            RenameColumn(table: "dbo.AspNetUserRoles", name: "UserId", newName: "ApplicationUser_Id");
            RenameColumn(table: "dbo.AspNetUserLogins", name: "UserId", newName: "ApplicationUser_Id");
            RenameColumn(table: "dbo.AspNetUserClaims", name: "UserId", newName: "ApplicationUser_Id");
            AddColumn("dbo.AspNetUserRoles", "RoleId", c => c.String(nullable: false, maxLength: 128));
            AddColumn("dbo.AspNetUserRoles", "UserId", c => c.String(nullable: false, maxLength: 128));
            AddColumn("dbo.AspNetUserLogins", "UserId", c => c.String(nullable: false, maxLength: 128));
            AddColumn("dbo.AspNetUserClaims", "UserId", c => c.String());
            CreateIndex("dbo.AspNetUserRoles", "IdentityRole_Id");
            CreateIndex("dbo.AspNetUserRoles", "ApplicationUser_Id");
            CreateIndex("dbo.AspNetUserLogins", "ApplicationUser_Id");
            CreateIndex("dbo.AspNetUserClaims", "ApplicationUser_Id");
            RenameTable(name: "dbo.AspNetRoles", newName: "IdentityRoles");
            RenameTable(name: "dbo.AspNetUserRoles", newName: "IdentityUserRoles");
            RenameTable(name: "dbo.AspNetUserLogins", newName: "IdentityUserLogins");
            RenameTable(name: "dbo.AspNetUserClaims", newName: "IdentityUserClaims");
            RenameTable(name: "dbo.AspNetUsers", newName: "ApplicationUsers");
        }
    }
}

运行update-database时的错误:

The object 'PK_dbo.AspNetUserLogins' is dependent on column 'UserId'.
ALTER TABLE DROP COLUMN UserId failed because one or more objects access this column.

【问题讨论】:

    标签: c# sql asp.net-mvc entity-framework asp.net-identity


    【解决方案1】:

    我知道你不会期待这样的答案,但我强烈建议不要合并。让 IdentityDbContext 活下去,它也会让你活下去。它是一个(唯一的)骗局。你将需要 2 个单独的数据库,我知道在 Azure 中这是额外的成本,但仍然......

    1. 如果您尝试生活在与 IdentityDbContext 合并的上下文中,则需要花费大量时间来发现其行为及其 EF 使用情况。把这段时间留给自己吧。
    2. 更多:您的身份 API(用户、角色、登录、锁定等)是显式类及其方法,而不是 EF。严格来说,您甚至不应该知道 Identity 子系统的持久性(EF + RDBMS)。 (将其视为一个黑匣子)
    3. 您对关系的看法是正确的,但再次重申:如果您有一个黑盒身份子系统,它提供所有服务(包括用户/密码/配置文件持久性)并且您想为使用完全相同的用户的商业案例?只需使用数据库中其他子系统提供的用户 ID。不要担心两个系统之间的引用完整性。考虑以下几点:在经过身份验证的会话中,您的用户 ID 将始终有效,否则您在身份验证过程中遇到严重问题,所以最重要的事情要担心...

    【讨论】:

    • 我遇到的另一个问题是我想为两个数据库播种,但我不确定这在两个上下文中的效果如何。
    • 另外,例如地址类有属性 public ApplicationUser Owner { get;放;如果它们不是同一上下文的一部分,我如何正确填充它们
    • 单独填充。这两个上下文没有任何关系,它们会起作用。
    • 这样我就可以去address.Owner,它会给我用户?
    • 是的,看起来我是个白痴,我的上下文可以处理我想要的种子和关系......
    猜你喜欢
    • 1970-01-01
    • 2016-07-21
    • 2018-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多