3

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 ?

Cagatay Kalan
  • 4,066
  • 1
  • 30
  • 23
  • 2
    possible duplicate of [EF: Validation failing on update when using lazy-loaded, required properties](http://stackoverflow.com/questions/6038541/ef-validation-failing-on-update-when-using-lazy-loaded-required-properties) – Diego Mijelshon Dec 15 '11 at 13:46

1 Answers1

1

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

Kamyar
  • 18,639
  • 9
  • 97
  • 171
  • is it a typo or did you add [Table("Address")] to your user class incorrectly? – Kamyar Dec 15 '11 at 11:37
  • if you set the AdressId as required, how can you create a User record with its Address at the same time ? The Address is not created in the database yet so it does not have an id. The id will be created when the identity field assigns the new id. So how can you set the AddressId of the person when it does not yet exist ? – Cagatay Kalan Dec 21 '11 at 13:47
  • i tried what you suggested and yes, fluent api can set a relation as required but this only delegates the required rule to the db by setting the foreign key as a non nullable field. However, since i have to remove the [Required] attribute from the model, still, the business model can't ensure the required rule. This is more accurately implemented in NHibernate and Hibernate so conceptually my problem is not solved yet. – Cagatay Kalan Dec 30 '11 at 22:22