2012-02-16 5 views
4

Я очень странное поведение с первым подходом и ассоциациями EF-кода. У меня есть два объекта:Entity framework 4.3 с обязательной ассоциацией

public class GlobalKpiSectionn 
{ 
    public GlobalKpiSection() 
    { 
     this.Regions = new HashSet<Region>(); 
    } 

    public virtual ICollection<Region> Regions { get; protected set; } 
} 

public class Region 
{ 
    public int RegionId { get; set; } 

    public bool IsMain { get; set; } 

    [Required] 
    public virtual GlobalKpiSection KpiSection { get; set; } 
} 

Мне нужен атрибут атрибута на свойстве KiSection, чтобы получить каскадные удаления.

Проблема заключается в следующем - в этом коде:

var mainRegion = context.Regions.Single(x => x.RegionId == id); 
mainRegion.IsMain = true; 
context.SaveChanges(); 

Я получаю исключение, что Обязательное поле не инициализирована. Но это подарок просто не загружен. Я не то, что писать везде явным, включает в себя свойства, когда я использую этот объект. Что я могу сделать, чтобы преодолеть это? Exceptoin details

UPDATE

Причина, почему я уверен, что его ленивая загрузка проблема в том, что:

 var primaryRegion = context.Regions 
            .Include(x => x.KpiSection) 
            .Single(x => x.RegionId == id); 

Решает проблему, но определенно ужасное решение.

+0

Вы использовали класс конфигурации для моделирования один ко многим отношений? – Jayanga

+0

Нет, его сопоставлены соглашениями – Sly

+0

Я думаю, что использование класса конфигурации в Fluent API было бы хорошим решением – Jayanga

ответ

10

Вот почему вы не должны использовать аннотации данных. Аннотации данных - это неправильная функция, потому что они выполняют как картографирование, так и проверку (нарушение единой ответственности) - как вы видите, это не всегда то, что вы хотите. Так что ваши текущие параметры:

  • Выключить проверку в context.Configuration.ValidateOnSaveEnabled = false
  • Expose нон обнуляемым KpiSectionId внешнего ключа свойство в вашем Region лица (вам не нужно будет Required атрибут навигационного свойства).
  • Использование свободно API вместо аннотации данных:

Пример:

modelBuilder.Entity<GlobalKpiSection>() 
      .WithMany(s => s.Regions) 
      .HasRequired(r => r.KpiSection); 
+0

«они выполняют как картографирование, так и проверку (нарушение единой ответственности)» Хорошо, вы, наконец, убедили меня отказаться от аннотаций данных в пользу для свободного API. Благодарю. –

1

EF отключил ленивую загрузку при проверке объектов. Он делает это, чтобы избежать ненужных обращений в базу данных из-за проверки, установленной на навигационные свойства.

Модель скалярного свойства в вашей сущности и поместите там атрибут проверки.

public class Region 
{ 
    public int RegionId { get; set; } 

    public bool IsMain { get; set; } 

    [Required] 
    public int? KpiSectionId { get; set; } 

    public virtual GlobalKpiSection KpiSection { get; set; } 
} 
2

Чтобы принудительно удалить каскады, вы должны свободно использовать конфигурации. Затем вы можете удалить атрибут [Required] из свойства KpiSection.

Что-то вроде этого:

public class GlobalKpiSectionn 
{ 
    public GlobalKpiSection() 
    { 
     this.Regions = new HashSet<Region>(); 
    } 

    public virtual ICollection<Region> Regions { get; protected set; } 
} 

public class Region 
{ 
    public int RegionId { get; set; } 

    public bool IsMain { get; set; } 

    public int GlobalKpiSectionId { get; set; } 
    public virtual GlobalKpiSection KpiSection { get; set; } 
} 

public class RegionConfig : EntityTypeConfiguration<Region> 
{ 
    HasRequired(x => x.KpiSection) 
     .WithMany(x => x.Regions) 
     .HasForeignKey(x => x.GlobalKpiSectionId) 
     .WillCascadeOnDelete(true); 
} 

public class YourContext : DbContext 
{ 
    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Configurations.Add(new RegionConfig()); 
    } 
} 
Смежные вопросы