2017-02-22 28 views
0

Я пытаюсь понять и доверять EF. У меня есть база данных со столами, и я пытаюсь реплицировать большую часть структуры EFCode-First Технология как упражнение, чтобы практиковать их основы.Несколько циклов DataAnnotation ForeignKeys или несколько каскадных путей Исключение

Все мои классы имеют «Hb» в качестве префикса в своих именах. Я хочу написать ссылки на объекты для других классов без «Hb» в имени свойства.

Я следовать инструкциям этого site

Первая причина реализации исключений, как:

Вводя ограничение внешнего ключа «FK_Common.HbZipcode_Common.HbCountry_CountryId» на столе «HbZipcode» может привести к циклов или нескольких каскадных путей. Указать DEL DELETE NO ACTION или ON UPDATE NO ACTION или изменить другие ограничения FOREIGN KEY . Не удалось создать ограничение или индекс. См. Предыдущие ошибок.

[Required, ForeignKey("Country")] 
public int CountryId { get; set; } 
public virtual HbCountry Country { get; set; } 

[Required, ForeignKey("State")] 
public int StateId { get; set; } 
public virtual HbState State { get; set; } 

[Required, ForeignKey("City")] 
public int CityId { get; set; } 
public virtual HbCity City { get; set; } 

// This Foreignkey never throw exception 
[ForeignKey("Neighborhood")] 
public int? NeighborhoodId { get; set; } 
public virtual HbNeighborhood Neighborhood { get; set; } 

я делаю что-то неправильно, и я не могу видеть.
Если бы кто-нибудь мог мне помочь, было бы хорошо.

Edit:

После нанесения раствора, принятый plushpuffin, все прошло, как ожидалось.
Вот код:

var modelConfig = dbModelBuilder.Entity<HbZipcode>(); 
modelConfig 
    .HasRequired(zc => zc.Country) 
    .WithMany(c => c.Zipcodes) 
    .HasForeignKey(zc => zc.CountryId) 
    .WillCascadeOnDelete(false); 

modelConfig 
    .HasRequired(zc => zc.State) 
    .WithMany(s => s.Zipcodes) 
    .HasForeignKey(zc => zc.StateId) 
    .WillCascadeOnDelete(false); 

modelConfig 
    .HasOptional(zc => zc.Neighborhood) 
    .WithMany(n => n.Zipcodes) 
    .HasForeignKey(zc => zc.NeighborhoodId) 
    .WillCascadeOnDelete(false); 

Delete cascade на HbZipcode сейчас происходит только тогда, когда HbCity удаляется

ответ

1

То, что здесь происходит, что HbZipCode имеет внешние ключи к нескольким таблицам, и вы не можете создать 2+ внешний ключ ограничение с ON CASCADE DELETE, которые имеют несколько способов удаления одних и тех же строк из одной таблицы.

Скорее всего, ваши классы объектов настроены так, что когда HbZipCode удаляется, он каскадирует удаление до HbNeighborhood, затем HbCity, затем HbState, а затем HbCountry. Если вы добавили еще один внешний ключ HbZipCode с ON CASCADE DELETE указывает на HbCity, удаление записи HbZipCode приведет к прямому каскадное удаление в HbNeighborhood и прямого каскада удаления в HbCity, но HbNeighborhood удаляемого бы также ПРИЧИНА каскад удалить до HbCity.

Что нужно сделать, это разрешить несколько путей каскадного удаления для HbCity и других типов сущностей, отключив CASCADE DELETE для большинства из них.

См. this MSDN page на бетонной конфигурации.

Вполне вероятно, что вы хотите что-то вроде этого:

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    modelBuilder.Entity<HbZipCode>() 
     .HasRequired(t => t.HbCity) 
     .WithMany(t => t.HbZipCodes) 
     .HasForeignKey(t => t.CityId) 
     .WillCascadeOnDelete(false); 
} 
+0

Я искажены направление удаления.Удаляется HbNeighborhood (и т. Д.), Который будет каскадировать удаление до HbZipCode. Извини за это. – plushpuffin

+0

Итак, я думаю, что рекомендуется удалить все ограничения «CASCADE» и явное обновление и удаление объектов на данный момент ... правильно? –

+0

Возможно, вам понадобится сохранить один набор триггеров с удалением каскада на самом прямом пути. Все зависит от ваших потребностей. – plushpuffin