Given this extremely simple model:
public class MyContext : BaseContext
{
public DbSet<Foo> Foos { get; set; }
public DbSet<Bar> Bars { get; set; }
}
public class Foo
{
public int Id { get; set; }
public int Data { get; set; }
[Required]
public virtual Bar Bar { get; set; }
}
public class Bar
{
public int Id { get; set; }
}
The following program fails:
object id;
using (var context = new MyContext())
{
var foo = new Foo { Bar = new Bar() };
context.Foos.Add(foo);
context.SaveChanges();
id = foo.Id;
}
using (var context = new MyContext())
{
var foo = context.Foos.Find(id);
foo.Data = 2;
context.SaveChanges(); //Crash here
}
With a DbEntityValidationException
. The message found in EntityValidationErrors
is The Bar field is required..
However, if I force loading of the Bar
property by adding the following line before SaveChanges
:
var bar = foo.Bar;
Everything works fine. This also works if I remove the [Required]
attribute.
Is this really the expected behavior? Are there any workarounds (besides loading every single required reference every time I want to update an entity)
Here's a semi-acceptable work-around:
I know it's a bit late... However, ill post this here. Since i too got horribly annoyed with this. Just tell EF to
Include
the required field.Notice the SMALL change
Ok, here is the real answer =)
First a little explanation
if you have a property (like your
Bar
) noting a FK (ForeignKey
), you can also have the corresponding FK field in your model so if we only need the FK and not the actualBar
we don't need it to go to the database:Now, to answer your question, what you can do to make the
Bar
asRequired
is to flag theBarId
property as required, but not theBar
itself:this works like a charm =)
Just had the same problem in EF 6.1.2. To solve this your class should be like the following:
As you can see, the "Required" attribute is not needed, because the Bar property is already required since the BarId property is not nullable.
So if you wanted the Bar property to be nullable, you would have to write:
Transparent workaround to ignore error on unloaded references
In your
DbContext
, overrideValidateEntity
method to remove validation error on references that are not loaded.Pros :
I found the following post that had an answer for the same problem:
My take on this is that is a pretty crappy proxy implementation. While unnecesarily walking the object graph and retriveing lazy-loaded properties is naturally something to be avoided (but apparently overlooked in Microsoft's first incarnation of EF), you shouldn't have to need to go un-proxying a wrapper to validate that it exists. On second thoughts, I'm not sure why you need to go walking the object graph anyway, surely the change tracker of the ORM knows what objects require validation.
I'm not sure why the problem exists, but I'm sure I wouldn't be having this problem if I was using say, NHibernate.
My 'workaround' - What I've done is define the Required nature of the relationship in a EntityTypeConfiguration class, and removed the Required attribute. This should make it work fine. It means that you will not validate the relationship, but it will fail the update. Not an ideal result.