Подтвердить что ты не робот

Entity Framework: почему метод WillCascadeOnDelete() игнорируется?

Вот моя ситуация:

public abstract class Article
{
    [key]
    public Guid Guid { get; set;}

    public string Name { get; set;}
    .
    .
    .
}

public class Download : Article
{
    ...
}

public abstract class Category : Article
{
    ...
}

public class DownloadCategory : Category 
{
    ....
}

И тогда у меня должно быть отношение "многие ко многим" между Download и DownloadCategory следующим образом:

public class DownloadInCategory
{
    [Key, Column(Order = 1), Required]
    [ForeignKey("Download")]
    Public Guid DownloadGuid { get; set; }

    Public Download Download { get; set; }

    [Key, Column(Order = 2), Required]
    [ForeignKey("Category")]
    Public Guid CategoryGuid { get; set; }

    Public DownloadCategory Category { get; set; }
}

Когда я вызываю Add-Migration, созданная миграция для объекта DownloadInCategory:

CreateTable("dbo.DownloadInCategories",
c => new
{
    CategoryGuid = c.Guid(nullable: false),
    DownloadGuid = c.Guid(nullable: false),
})
.PrimaryKey(t => new { t.CategoryGuid, t.DownloadGuid })
.ForeignKey("dbo.DownloadCategories", t => t.CategoryGuid)
.ForeignKey("dbo.Downloads", t => t.DownloadGuid, cascadeDelete: true)
.Index(t => t.CategoryGuid)
.Index(t => t.DownloadGuid);

Вот мой вопрос: Как вы заметили, это не добавление cascadeDelete: true к одному из внешних ключей. ПОЧЕМУ?????!!!!!!

Я должен упомянуть, что я не изменил никаких соглашений modelbuilder. Таким образом, эта схема должна добавить Casscade в delete при миграции. Мои свойства [Required].

Что я делаю неправильно?

Спасибо, ребята...

Обновление: Обратите внимание, что классы Article и Category abstract. Я изменил классы выше

Обновление 2: В этой схеме нет логической проблемы. Если я вручную отредактирую миграцию, он будет нормально обновлять базу данных.

Обновление 3: Моя методология наследования EF TPC

Обновление 4: После некоторых исследований и тестов Кажется, проблема наследуется от Category. Когда DownloadCategory Унаследовано от Category, Cascade не развертывается. но когда я наследую DownloadCategory непосредственно из статьи, развертывается Cascade. Но почему снова?

4b9b3361

Ответ 1

Я бы подумал, что это происходит потому, что:

DownloadCategory : Category : Article

против

Download : Article

Ключ находится в классе Article. Несколько DownloadCategories могут использовать один и тот же Category, поэтому он не будет каскадом при удалении, так как это может привести к повреждению других DownloadCategory.

Возможно, это ошибка в Entity Framework, так как вы используете TPC, это должно быть выведено. Посмотрите эту статью для обходных путей.

В частности, эти разделы:

В большинстве случаев Entity Framework может вывести, какой тип зависимый и который является основным в отношениях. Однако, когда оба конца связи необходимы или обе стороны являются необязательными инфраструктура Entity Framework не может идентифицировать зависимую и основную. когда оба конца отношения необходимы, используйте WithRequiredPrincipalили WithRequiredDependent после метода HasRequired. Когда оба конца отношения являются необязательными, используйте WithOptionalPrincipal или WithOptionalDependent после метода HasOptional.

// Configure the primary key for the OfficeAssignment 
modelBuilder.Entity<OfficeAssignment>() 
    .HasKey(t => t.InstructorID); 

modelBuilder.Entity<Instructor>() 
    .HasRequired(t => t.OfficeAssignment) 
    .WithRequiredPrincipal(t => t.Instructor);

Вы можете настроить каскадное удаление в отношениях, используя WillCascadeOnDelete. Если внешний ключ на зависимом объекте не является нулевым, то Code First устанавливает каскадное удаление на отношения. Если внешний ключ на зависимом объекте является нулевым, Код First не устанавливает каскадное удаление в отношении, и когда главный удаляется, внешний ключ будет установлен на null.

Вы можете удалить эти соглашения об исключении каскадов, используя:

modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>()
modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>()

Следующий код настраивает требуемое соотношение, а затем отключает каскадное удаление.

modelBuilder.Entity<Course>() 
    .HasRequired(t => t.Department) 
    .WithMany(t => t.Courses) 
    .HasForeignKey(d => d.DepartmentID) 
    .WillCascadeOnDelete(false);