Quantcast
Channel: Development With A Dot
Viewing all articles
Browse latest Browse all 404

Entity Framework Pitfalls – Deleting Detached Entities With Required References

$
0
0

It is common practice in O/RMs to delete an entity without actually loading id, just by knowing its id. This saves one SELECT and is great for performance. For example, using Entity Framework Code First:

   1: ctx.Entry(new Project { ProjectId = 1 }).State = EntityState.Deleted;
   2: ctx.SaveChanges();

This, however will fail if there is a [Required] reference (might be defined in fluent configuration, it doesn’t matter) to another entity (many-to-one, one-to-one)! For example, if our Product entity would have something like this:

   1:publicclass Project
   2: {
   3:public Int32 ProjectId { get; set; }
   4:  
   5:     [Required]
   6:publicvirtual Customer Customer { get; set; }
   7:  
   8://...
   9: }

In this case, the required constraint is treated like a concurrency check and the above query will fail miserably. From conversations with the EF team, I understood this is related with some EF internals, which apparently are difficult to change.

There are three workarounds, though:

  1. Remove the required constraint, which may not be appropriate at all;
  2. Load the entity into the context, which, of course, was exactly what we were trying to avoid;
  3. Add a foreign key property for the navigation property.

The third option would be to have something like:

   1:publicclass Project
   2: {
   3:public Int32 ProjectId { get; set; }
   4:  
   5:     [Required]
   6:publicvirtual Customer Customer { get; set; }
   7:  
   8:     [ForeignKey("Customer")]
   9:public Int32 CustomerId { get; set; }
  10:  
  11://...
  12: }

It really shouldn’t be required to have this foreign key – that’s what navigation properties are meant to replace – but it is. Let’s hope that some future version of EF will fix this.


Viewing all articles
Browse latest Browse all 404

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>