I found out that, if i set a navigation property as required ( using the Required attribute ) and use lazy-loading proxies, when i load the parent entity and do nothing but try to save in the same context, an EntityValidationError occurs which is like "xxx field is required".
With hibernate in Java and NHibernate in .NET, it is possible to just fetch an entity without its navigation properties ( all lazy loaded ) , update it and save again. The framework realizes that nothing changed with the navigation references and do not throw any errors.
The example is below
[Table("Address")]
public class Address
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int AddressId { get; set; }
[Required, StringLength(512)]
public virtual string AddressLine1 { get; set; }
}
[Table("User")]
public class User
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
[Required]
public string Name {get; set;}
[Required]
public virtual Address Address {get; set;}
}
void LoadAndSaveUser() {
var user = Context.Users.First();
user.Name = "foo";
// if i comment out this line
// ( probably EF fetches the lazy loaded entiy )
// the code works. it is strange though because i don't access any property/method of the Address
// var dummy = user.Address
Context.SaveChanges();
}
When i try this without the "Required" attribute on the Address property, no error occurs. With the Required attribute, i get "Address field is required!". Since each user should have an address, i want the attribute to create a consistent model.
In some forums, i found posts suggesting to include the navigation property while loading the parent entity ( eager load in other words ) but it is not a feasible approach if we have too many navigation properties.
Am i doing something wrong or is there any other way to implement such funcionality ?
Define public int AddressId in your User class. It loads whenever a user is loaded. I think that will solve the problem.
Update:
Well, I have reproduced your problem. You have a couple of options to prevent this. But one thing's for sure. You have to remove the [Required] attribute from your Address property. This is the source of your problem (which is rational since you are telling EF "I want the Address object (not the foreign key but the navigation property) to be present. if it's null, throw an exception").
Also, define AddressId property of type int in your User class.
Notice that you can also define public virtual ICollection<User> Users { get; set; } in your Address entity.
You can tell EF about required attribute either by putting [Required] on AddressId, or by using fluent api:
in your user-mapping class:
this.HasRequired(t => t.Address)
.WithMany()
.HasForeignKey(d => d.AddressId);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With