2

I am trying to simply load an entity, modify a property and then save it back to the database.

var db = new NewsletterContext();
var newsletter  = db.Newsletters.Find(x => x.ID==newsletterID); 
newsletter.SomeProperty = 5;
db.SaveChanges();

This causes a validation error as there are some properties on the newsletter object which are required and apparently not loaded when I do a Find().

I can solve this using an Include() for each required property followed by a Where():

var db = new NewsletterContext();
var newsletter  = db.Newsletters.Include(x => x.RequiredProp1)
                    .Include(x => x.RequiredProp2).Include(x => x.RequiredProp3)
                    .Where(x => x.ID==newsletterID)
                    .FirstOrDefault(); 
db.SaveChanges();

This isn't a very elegant solution and will break if I add more required properties to the Newsletter object.

Is there a better solution?

2
  • Yes, sorry just the terminology. RequiredProp1 etc are actually related entities. The newsletter entity itself loads fine and I can read all the properties but saving back causes the error. Commented Jan 9, 2012 at 6:11
  • EF 4.1 code first with .NET 4.0 in an MVC 3 app. Commented Jan 9, 2012 at 6:31

2 Answers 2

6

Entity framework will disable lazy loading when doing the validation. Hence if you put required validation on navigational properties the validation will fail. You can decorate the scalar property related to the navigational property instead.

public class Foo
{

    [Required]
    public int? RequiredScalarId { get; set; }

    public virtual Bar RequiredNavigationalProp { get; set; }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Doesn't this just add another (perhaps un-necessary) field to the database? Is there a way to programmatically turn on lazyloading for the validation?
@Judo Lazy loading on validation is disabled because of the exact reason. Avoid unnecessary lazy loading. Having the scalar property is convenient like in this case. It does not add a field to the database.
1

Do not want to pollute your model with foriegn keys? Good! Read on. Instead you can override the SaveChanges method in NewsletterContext. Get all modified entities and using reflection, load all their lazy loaded properties and collections using the following sample syntax:

db.Entry(newsletter).Reference(n => n.RequiredProp1).Load();
db.Entry(newsletter).Collection(n => n.RequiredCollec1).Load();

It won't be easy as it sounds, but once you are have written it, it would feel so good to see it work seamlessly :)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.