Укажите ON DELETE NO ACTION в ASP.NET MVC 4 С# Code First
Как мне указать ON DELETE NO ACTION Внешнее ограничение ключа в моих моделях модели?
В настоящее время у меня есть:
public class Status
{
[Required]
public int StatusId { get; set; }
[Required]
[DisplayName("Status")]
public string Name { get; set; }
}
public class Restuarant
{
public int RestaurantId { get; set; }
[Required]
public string Name { get; set; }
[Required]
[EmailAddress]
public string Email { get; set; }
[Required]
public string Telephone { get; set; }
[Required]
public int StatusId { get; set; }
public List<Menu> Menus { get; set; }
// NAVIGATION PROPERTIES
public virtual Status Status { get; set; }
}
public class Menu
{
public int MenuId { get; set; }
[Required]
public int RestaurantId { get; set; }
[Required]
public string Name { get; set; }
[Required]
public int StatusId { get; set; }
// NAVIGATION PROPERTIES
public virtual Status Status { get; set; }
public virtual Restaurant Restaurant { get; set; }
}
И мой DbContext:
public class MenuEntities : DbContext
{
public DbSet<Status> Statuses { get; set; }
public DbSet<Restaurant> Restaurants { get; set; }
public DbSet<Menu> Menus { get; set; }
}
Как вы можете видеть:
- В ресторане есть много меню.
- Ресторан имеет один статус.
- a Меню принадлежит 1 ресторану
- Обе рестораны и меню имеют 1 статус. (Live, Invisible, Draft)
Естественно, если статус удаляется, я, конечно, не хочу каскад, так как это все испортит.
UPDATE:
Марк Орета упоминает следующее в следующем примере:
modelBuilder.Entity<FirstEntity>()
.HasMany(f => f.SecondEntities)
.WithOptional()
.WillCascadeOnDelete(false);
Где я могу поместить этот код? В моем классе MenuEntities/DbContext?
Может ли кто-нибудь привести пример этого использования?
UPDATE:
Получил этот бит, работающий сейчас, однако это создало ошибку ограничения множественности при попытке засеять DB...
Multiplicity constraint violated. The role 'Menu_Status_Source' of the relationship 'LaCascadaWebApi.Models.Menu_Status' has multiplicity 1 or 0..1.
Мой инициализатор базы данных:
http://pastebin.com/T2XWsAqk
Ответы
Ответ 1
Вы можете отключить его для всего контекста, удалив соглашение об исключении каскада в методе OnModelCreating:
protected override void OnModelCreating( DbModelBuilder modelBuilder )
{
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
}
или вы можете сделать это за отношения, используя свободное отображение (также в OnModelCreating):
РЕДАКТИРОВАТЬ: вы поместите его в объекты меню
public class MenuEntities : DbContext
{
public DbSet<Status> Statuses { get; set; }
public DbSet<Restaurant> Restaurants { get; set; }
public DbSet<Menu> Menus { get; set; }
protected override void OnModelCreating( DbModelBuilder modelBuilder )
{
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
modelBuilder.Entity<Menu>()
.HasRequired( f => f.Status )
.WithRequiredDependent()
.WillCascadeOnDelete( false );
modelBuilder.Entity<Restaurant>()
.HasRequired( f => f.Status )
.WithRequiredDependent()
.WillCascadeOnDelete( false );
}
}
Ответ 2
Просто сделайте свойство FK обнуляемым, тогда каскадное удаление исчезнет.
public int? StatusId { get; set; }
Ответ 3
После внесения изменений в модель убедитесь, что вы обновили файл миграции, добавив параметр -Force.
Add-MigrationMigrationName -Force
Ответ 4
Поместите это в свой класс MenuEntities
(класс, который сходит с DbContext
):
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
}
Ответ 5
добавить эту строку в конец поля в контексте;
.OnDelete(DeleteBehavior.Restrict);
Ответ 6
Чтобы добиться применения этого на всех объектах, измените внешние ключи DeleteBehavior
на Restrict
. Мы делаем это в методе OnModelCreating()
класса AppDbContext
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
foreach (var foreignKey in modelBuilder.Model.GetEntityTypes().SelectMany(e => e.GetForeignKeys()))
{
foreignKey.DeleteBehavior = DeleteBehavior.Restrict;
}
}
Постройте решение. Добавьте новую миграцию и обновите базу данных.