Entity Framework 4.1 code-first, required lazy load reference is null on save

泪湿孤枕 提交于 2019-12-07 09:05:31

问题


I'm building a forum project for ASP.NET MVC 3, running on .NET 4 with the latest version of Entity Framework.

I have the usual forum design, with a Board with Categories, and Categories with Forums, Forums with Topics and Topics with Posts etc.

Simplified:

public class Category {
    [Required]
    public virtual Board Board { get; set; }
}
public class Forum {
    [Required]
    public virtual Category Category { get; set; }
}
public class Topic {
    [Required]
    public virtual Forum Forum { get; set; }
}
public class Post {
    [Required]
    public virtual Topic Topic { get; set; }
}

When a new post is created the topic is informed, and when a topic is changed, the forum is informed.

So, again simplified:

public class Forum {
    public void TopicChanged(Topic topic) {
        // Do stuff
    }
}
public class Topic {
    public void PostAdded(Post post) {
        // Do stuff
        this.Forum.TopicChanged(this);
    }
}

So after creating a new Post (and committing it to the database), I call PostAdded on the parent topic. Now this is where it get odd!

When I commit the changes to my repositories, I get a validation error, Category on Forum is required.

If I look in the database, the Forum has a reference to the parent Category. If I stop the code and looks at the Forum object, it has a Category instance. So this looks like an issue with lazy loading, especially because if I add this line:

var cat = this.Category

At the bottom of the TopicChanged method in the Forum class, there's no longer any errors.

Am I doing something totally wrong here, have I run into a borderline issue, or what is going on? I figured EF would see that the reference is a lazy loaded reference, and if it hasn't been changed, there's no reason why this should fail on save???

Thanks, Steen


回答1:


I've fixed my problem. It might not be a really nice and clean solution, but at least I can handle this situation now, without having to change a lot of my code (which needs to run with nHibernate also). So no dirty solution.

Just to give you an idea on how it's solved, I'll try and explain it here.

On the Commit() method on my repository, I start off calling GetValidationErrors() on the DbContext instance. This returns the error I encountered above along with the entity where the error occurs. On the base type of this entity (the entity is a proxy generated by EF) I run through all properties and when I encounter a property with the Required attribute, I call GetValue on the identical property on the proxy object.

Enough talk, more code:

var errors = this.context.GetValidationErrors();
foreach (DbEntityValidationResult result in errors) {
    Type baseType = result.Entry.Entity.GetType().BaseType;
    foreach (PropertyInfo property in result.Entry.Entity.GetType().GetProperties()) {
        if (baseType.GetProperty(property.Name).GetCustomAttributes(typeof(RequiredAttribute), true).Any()) {
            property.GetValue(result.Entry.Entity, null);
        }
    }
}


来源:https://stackoverflow.com/questions/7496076/entity-framework-4-1-code-first-required-lazy-load-reference-is-null-on-save

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!