Entity framework 4.3 with required connection

I have very weird behavior with the first approach and EF code associations. I have two objects:

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 the required KiSection property attribute to get cascading deletes.

The problem is this: in this code:

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

I get an exception that the required field is not initialized. But he present just not loaded. I am not something to write explicit everywhere, it includes properties when I use this object. What can I do to overcome this? Exceptoin details

UPDATE

The reason I'm sure her lazy loading problem is this:

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

Solves the problem, but its definitely a terrible solution.

+4
source share
3 answers

This is why you should not use data annotations. Data annotations are a wrong function because they perform both mapping and verification (violation of a single responsibility) - as you can see, this is not always what you want. So your current options are:

  • Disable validation in context.Configuration.ValidateOnSaveEnabled = false
  • Output the invalid KpiSectionId foreign key property to your Region object (you do not need the Required attribute in your navigation property).
  • Use a free API instead of data annotations:

Example:

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

To force cascades to be removed, you must use the free configuration. You can then remove the [Required] attribute from the KpiSection property.

Something like that:

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

EF turned off lazy loading when checking objects. He does this to avoid unnecessary round trips to the database due to checks set for navigational properties.

Match 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; } } 
+1
source

Source: https://habr.com/ru/post/1396819/


All Articles