2012-02-16 46 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()); 
    } 
}