2015-06-09 3 views
13

Вот моя ситуация: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 
{ 
    .... 
} 

И тогда я должен иметь много-ко-многим между скачать и 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); 

Вот мой вопрос: Как вы NOTIC e он не добавляет cascadeDelete: true к одному из внешних ключей. ЗАЧЕМ!!!!!!?????

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

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

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

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

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

Update 3: My EF Наследование Методология является TPC

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

+0

Если редактирование миграции вручную работает отлично, это скорее теоретический вопрос о том, почему каскадное удаление не выводится? – jjj

+5

@jjj Нет. Это совершенно практично с моей точки зрения. Ручное редактирование миграции не является хорошей практикой. В более крупных проектах, таких как тот, над которым я работаю, делает такое, что добавляет больше соображений по обслуживанию и разработке новых функций для проекта. Я думаю, что редактирование вручную неправильно. и миграция должна соответствовать схеме моделей. – abzarak

+4

Я полагаю, что это было бы правдой в идеальном мире, где встроенные соглашения были бы идеальными. Вы можете вникнуть в исходный код, чтобы выяснить, почему это произошло в этом случае, но я предполагаю, что это результат ярлыка, чтобы избежать циклов. – jjj

ответ

3

Я думаю, это потому, что:

DownloadCategory : Category : Article 

против

Download : Article 

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

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

Конкретно эти разделы:

В большинстве случаев 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. Если внешний ключ зависимого объекта не имеет значения NULL, то 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); 
+0

спасибо. Статья и класс категории являются абстрактными. Я обновляю свой вопрос, говоря, что они абстрактные. – abzarak

+0

Я не уверен, как это имеет значение? –

+0

Если класс категории является абстрактным, экземпляров для категории напрямую не будет. И экземпляры из DownloadCategory. поэтому «Несколько DownloadCategories могут использовать одну и ту же категорию» здесь не имеет смысла ... – abzarak