Я хочу перейти от неявной таблицы сопоставления к явной.
Я начинаю с этих классов
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), и это сработало - единственное отличие состоит в том, что имя таблицы сопоставления совпадает с именем объекта помощника сопоставления.