Entity framework 4.3 with required association

删除回忆录丶 提交于 2019-12-01 04:02:37

问题


I'm a very strange behavior with EF code first approach and associations. I have two entities:

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

I need required attribute on KiSection property in order to get cascade deletes.

The problem is the following - in this code:

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

I'm getting exception that Required field is not initialized. But it is present just not loaded. I don't what to write everywhere explicit includes for properties when I use this entity. What can I do to overcome this?

UPDATE

The reason why I'm sure its lazy loading issue is that:

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

Solves the issue, but its definitely awful solution.


回答1:


That is why you should not use data annotations. Data annotations are wrong feature because they do both mapping and validation (violation of single responsibility) - as you see it is not always what you want. So your current options are:

  • Turn off validation in context.Configuration.ValidateOnSaveEnabled = false
  • Expose non nullable KpiSectionId foreign key property in your Region entity (you will not need Required attribute on your navigation property).
  • Use fluent API instead of data annotations :

Example:

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



回答2:


To force cascade deletes, you have to use the fluent configurations. You can then remove the [Required]attribute from the KpiSection property.

Something like this:

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



回答3:


EF disabled lazy loading when it validates the entities. It does this to avoid unnecessary round trips to database due to the validations placed on navigational properties.

Model the scalar property in your entity and place the validation attribute there.

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


来源:https://stackoverflow.com/questions/9310183/entity-framework-4-3-with-required-association

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!