EF CTP4 каскадное удаление на многие для многих отношений
Я создал отношение многие ко многим, используя стандартные соглашения в EF CTP4, определив ICollection как для изображений, так и для объектов проекта.
Таблица сопоставления создается следующим образом:
create table [dbo].[Images_Project] (
[Images_Id] [uniqueidentifier] not null,
[Project_Id] [uniqueidentifier] not null,
primary key ([Images_Id]));
К сожалению, когда я удаляю проект, это не каскадное удаление в таблицу отображения изображений.
Я ожидаю, что EF сгенерирует ключ для свойств Imanges_Id и Project_Id, но это не так. Как настроить EF для удаления отображений изображений при удалении проекта? (только запись отображения изображения, а не запись изображения)
Спасибо
[Обновить]
Хотя каскад, по-видимому, не представляется возможным, любая идея, почему следующий тест проходит:
[Test]
public void Can_delete_project_with_images()
{
var project = new Project { Title = "Test project" };
var image = new Image { Title = "Some image" };
project.AddImage(image);
context.Set<Project>().Add(project);
context.SaveChanges();
object id = project.Id;
object imageId = image.Id;
var fromDb = context.Projects.Find(id);
fromDb.ShouldNotBeNull();
context.Set<Project>().Remove(fromDb);
context.SaveChanges();
var fromDb2 = context.Images.Find(imageId);
fromDb2.ShouldNotBeNull();
fromDb2.Title.ShouldEqual("Some image");
}
2 ответа
Начиная с EF CTP4, нет возможности напрямую включить каскадные удаления для ассоциаций "многие ко многим" в свободном API. Единственный способ добиться этого - явно поместить таблицу ссылок в объектную модель:
public class Project
{
public int Id { get; set; }
public ICollection<ProjectXrefImage> Images { get; set; }
}
public class ProjectXrefImage
{
[Key][DataMember(Order = 1)]
public int ProjectId { get; set; }
[Key][DataMember(Order = 2)]
public int ImageId { get; set; }
public Project Project { get; set; }
public Image Image { get; set; }
}
public class Image
{
public int Id { get; set; }
public virtual ICollection<ProjectXrefImage> Projects { get; set; }
}
public class MyContext : DbContext
{
public DbSet<Project> Projects { get; set; }
public DbSet<Image> Images { get; set; }
public DbSet<ProjectXrefImage> ProjectsXrefImages { get; set; }
}
Тем не менее, я лично не буду этого делать и буду вручную включать их в базу данных.
Обновить:
Как вы обнаружили в тестовом примере, код сначала позаботится о каскадном удалении на стороне клиента, даже если он не включен в хранилище данных. Это означает, что когда вы удаляете проект, вызывая метод Remove(), код сначала достаточно умен, чтобы сначала отправить оператор удаления, чтобы избавиться от зависимой записи из таблицы ссылок (Images_Projects), а после этого он отправит другой оператор удаления в удалить запись проекта. Я проверю это с помощью SQL Profiler.
Вот почему мы не можем включить каскадное удаление на многих отношениях, потому что нам это не нужно! Соглашение, которое я объяснил выше, позаботится об этом для нас!
SQL Server не позволяет выполнять циклическое каскадное удаление.