EF6: переход от неявной к явной таблице сопоставления «многие ко многим» приводит к повторному созданию таблицы - PullRequest
0 голосов
/ 15 апреля 2019

Я хочу перейти от неявной таблицы сопоставления к явной.

Я начинаю с этих классов

public class Node
{ 
     [Key]
     public Guid Id {get; set;}

     public virtual HashMap<AspNetUser> AspNetUsers {get; set;} 
}

public class AspNetUser
{ 
    [Key]
    [StringLength(128)]
    public string Id { get; set; }

     public virtual HashMap<Node> Nodes {get; set;} 
}

и следующее отображение кода

        modelBuilder.Entity<AspNetUser>()
            .HasMany(e => e.Nodes)
            .WithMany(e => e.AspNetUsers)
            .Map(m => m.ToTable("AccessibleNodes").MapLeftKey("AdminId").MapRightKey("NodeId"));

Теперь, когда в моей явной таблице сопоставления я создал этот вспомогательный объект

public class AccessibleNode
{
    public string AdminId { get; set; }

    public Guid NodeId { get; set; }

    public virtual AspNetUser Admin { get; set; }

    public virtual Node Node { get; set; }

}

и адаптировал мои объекты следующим образом

public class Node
{ 
     [Key]
     public Guid Id {get; set;}

     public virtual HashMap<AccessibleNode> AspNetUsers {get; set;} 
}

public class AspNetUser
{ 
    [Key]
    [StringLength(128)]
    public string Id { get; set; }

     public virtual HashMap<AccessibleNode> Nodes {get; set;} 
}

и, наконец, изменил код первого сопоставления кода следующим образом

        modelBuilder.Entity<AccessibleNode>()
            .HasKey(x => new { x.AdminId, x.NodeId }).ToTable("AccessibleNodes");

        modelBuilder.Entity<AccessibleNode>()
            .HasRequired(x => x.Admin)
            .WithMany(x => x.Nodes)
            .HasForeignKey(x => x.AdminId).WillCascadeOnDelete();
        modelBuilder.Entity<AccessibleNode>()
            .HasRequired(x => x.Node)
            .WithMany(x => x.AspNetUsers)
            .HasForeignKey(x => x.NodeId).WillCascadeOnDelete();

К сожалению, это изменение вызывает миграцию. Глядя на сценарий, который он генерирует, он имеет мало смысла

IF object_id(N'[dbo].[FK_dbo.AccessibleNodes_dbo.AspNetUsers_AdminId]', N'F') IS NOT NULL
    ALTER TABLE [dbo].[AccessibleNodes] DROP CONSTRAINT [FK_dbo.AccessibleNodes_dbo.AspNetUsers_AdminId]
IF object_id(N'[dbo].[FK_dbo.AccessibleNodes_dbo.Nodes_NodeId]', N'F') IS NOT NULL
    ALTER TABLE [dbo].[AccessibleNodes] DROP CONSTRAINT [FK_dbo.AccessibleNodes_dbo.Nodes_NodeId]
CREATE TABLE [dbo].[AccessibleNodes] (
    [AdminId] [nvarchar](128) NOT NULL,
    [NodeId] [uniqueidentifier] NOT NULL,
    CONSTRAINT [PK_dbo.AccessibleNodes] PRIMARY KEY ([AdminId], [NodeId])
)
DROP TABLE [dbo].[AccessibleNodes]
ALTER TABLE [dbo].[AccessibleNodes] ADD CONSTRAINT [FK_dbo.AccessibleNodes_dbo.AspNetUsers_AdminId] FOREIGN KEY ([AdminId]) REFERENCES [dbo].[AspNetUsers] ([Id]) ON DELETE CASCADE
ALTER TABLE [dbo].[AccessibleNodes] ADD CONSTRAINT [FK_dbo.AccessibleNodes_dbo.Nodes_NodeId] FOREIGN KEY ([NodeId]) REFERENCES [dbo].[Nodes] ([Id]) ON DELETE CASCADE

Как видите, он удаляет существующие ограничения, затем пытается создать таблицу, которая уже существует, затем пытается удалить ее и, наконец, восстановить ограничения. Две вещи здесь: СОЗДАТЬ, а затем УБРАТЬ? Это бессмысленно. И ... глядя на существующую структуру БД, на мой взгляд, это похоже на то, что она пытается создать. Итак ... где я иду не так? Я сделал то же самое для другого объекта (также связанного с AspNetUser), и это сработало - единственное отличие состоит в том, что имя таблицы сопоставления совпадает с именем объекта помощника сопоставления.

...