Миграции EF с моделью в другом проекте

#c# #entity-framework #asp.net-core #migration

#c# #entity-framework #asp.net-ядро #миграция

Вопрос:

Каждый раз, когда я запускаю команду Add-Migration -Context ApplicationDbContext в консоли диспетчера пакетов, миграция, похоже, пытается создать таблицу, которая уже существует в другом DbContext.

У меня следующая структура проекта:

введите описание изображения здесь

Таблица, которую я хотел бы создать, — это CheckoutToken модель:

 public class CheckoutToken
{
   [Key]
   public string Token { get; set; }

   public string UserId { get; set; }

   public int LicenseId { get; set; }

   public DateTime Created { get; set; }

   public DateTime Expires { get; set; }

   public License License { get; set; }

   public virtual ApplicationUser User { get; set; }
}
  

ApplicationUser Модель — это таблица, которая существует, это модель:

 public class ApplicationUser : IdentityUser
{
   public bool SmsTwoFactorEnabled { get; set; }
}
  

Когда я запускаю команду Add-Migration, я получаю миграцию, которая выглядит так, как будто она пытается создать таблицу с именем «ApplicationUser» в таком Up() методе:

 migrationBuilder.CreateTable(
  name: "ApplicationUser",
  columns: table => new
  {
     Id = table.Column<string>(nullable: false),
     UserName = table.Column<string>(nullable: true),
     NormalizedUserName = table.Column<string>(nullable: true),
     Email = table.Column<string>(nullable: true),
     NormalizedEmail = table.Column<string>(nullable: true),
     EmailConfirmed = table.Column<bool>(nullable: false),
     PasswordHash = table.Column<string>(nullable: true),
     SecurityStamp = table.Column<string>(nullable: true),
     ConcurrencyStamp = table.Column<string>(nullable: true),
     PhoneNumber = table.Column<string>(nullable: true),
     PhoneNumberConfirmed = table.Column<bool>(nullable: false),
     TwoFactorEnabled = table.Column<bool>(nullable: false),
     LockoutEnd = table.Column<DateTimeOffset>(nullable: true),
     LockoutEnabled = table.Column<bool>(nullable: false),
     AccessFailedCount = table.Column<int>(nullable: false),
     SmsTwoFactorEnabled = table.Column<bool>(nullable: false)
   },
   constraints: table =>
   {
      table.PrimaryKey("PK_ApplicationUser", x => x.Id);
   });
  

Я не уверен, что я здесь делаю не так, я думал, что EF будет знать, что ApplicationUser — это AspNetUsers таблица, и что, связывая связь с внешним ключом CheckoutToken , он будет знать, что это зависимость, а не новая таблица.

У меня также нет таблицы ApplicationUser в моем DbContext в качестве DbSet:

 public class ApplicationDbContext : DbContext
    {
        public DbSet<LicenseType> LicenseTypes { get; set; }
        public DbSet<License> Licenses { get; set; }
        public DbSet<CheckoutToken> CheckoutTokens { get; set; }

        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
       : base(options)
        { }

        protected override void OnModelCreating(ModelBuilder builder)
        {
            builder.SeedEnumValues<LicenseType, LicenseTypeEnum>(e => e);
        }
    }
  

Кто-нибудь знает, что я делаю не так? Я уже несколько дней в замешательстве

Ответ №1:

Поскольку в вашем приложении есть два контекста БД (IdentityDbContext и ApplicationDbContext), возможно, они используют другую базу данных для хранения таблицы. Вы можете проверить метод ConfigureServices в файле Startup.cs или IdentityHostingStartup.cs, чтобы убедиться, что они используют одну и ту же строку подключения.

         services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(
                Configuration.GetConnectionString("IndentityDbContextConnection"))); 

            services.AddDbContext<IndentityDbContext>(options =>
                options.UseSqlServer(
                 Configuration.GetConnectionString("IndentityDbContextConnection")));
  

Кроме того, для ApplicationDbContext попробуйте изменить код, как показано ниже:

 public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
  

Затем включите миграцию, чтобы проверить результат.

Редактировать:

Если все еще не работает, попробуйте удалить ненужный оператор в методах Up() и Down() .

Кроме того, если вы встретите новое свойство, которое не добавляется к проблеме AspNetUsers, попробуйте добавить следующий код, например, в метод Up() / Down() (используя следующий код для добавления столбцов адресов в таблицу AspNetUsers, после этого обновите базу данных с помощью миграции):

     protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.AddColumn<int>(
         name: "Address",
         table: "AspNetUsers",
         nullable: false,
         defaultValue: 0);
    }

    protected override void Down(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.DropColumn(
         name: "Address",
         table: "AspNetUsers");
    }
  

Комментарии:

1. Хотя я извлек из .NET Core IdentityDbContext<ApplicationUser> , когда я создаю миграцию, похоже, что она пытается создать все таблицы идентификаторов, т. е. AspNetUsers, AspNetRoles и т. Д.. Я также проверил, чтобы убедиться Startup.cs , что файл и проверил, используют ли оба контекста одну и ту же строку подключения, и это правда.

2. @KTOV, попробуйте удалить ненужный оператор в методах Up() и Down().