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 не позволяет выполнять циклическое каскадное удаление.

Другие вопросы по тегам