2012-02-16 69 views
4

我是一個非常奇怪的行爲與EF代碼的第一種方法和關聯。我有兩個實體:實體框架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 2012-02-16 11:20:04

+0

不,按照約定映射 – Sly 2012-02-16 11:21:22

+0

我認爲在Fluent API中使用配置類將是一個很好的解決方案 – Jayanga 2012-02-16 11:26:31

回答

10

這就是爲什麼你不應該使用數據的註釋。數據註釋是錯誤的功能,因爲它們既執行映射和驗證(違反單一責任) - 正如您所看到的,它並不總是您想要的。所以,當前的選項有:

  • 關閉驗證,在context.Configuration.ValidateOnSaveEnabled = false
  • Region實體揭露非可空KpiSectionId外鍵屬性(你不需要在你的導航屬性Required屬性)。
  • 用流利的API,而不是數據註釋:

例子:

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

「他們既進行映射和驗證(違反單一責任)」好吧,您終於說服我放棄數據註釋青睞流暢的API。謝謝。 – 2012-10-16 02:55:02

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

要強制級聯刪除,必須使用流暢配置。然後可以從KpiSection屬性中刪除[Required]屬性。

事情是這樣的:

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()); 
    } 
}