实体框架4.1代码优先,所需的延迟加载引用在保存时为null

Ste*_*rup 4 lazy-loading entity-framework-4.1 asp.net-mvc-3

我正在为ASP.NET MVC 3构建一个论坛项目,在.NET 4上运行最新版本的Entity Framework.

我有通常的论坛设计,董事会与类别,类别与论坛,论坛与主题和主题与帖子等.

简化:

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; }
}
Run Code Online (Sandbox Code Playgroud)

创建新帖子时,将通知主题,并在更改主题时通知论坛.

所以,再次简化:

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

因此,在创建一个新的Post(并将其提交到数据库)之后,我在父主题上调用PostAdded.现在这是奇怪的地方!

当我将更改提交到我的存储库时,我收到验证错误,需要在论坛上分类.

如果我查看数据库,论坛会引用父类别.如果我停止代码并查看Forum对象,它就有一个Category实例.所以这看起来像延迟加载的问题,特别是因为如果我添加这一行:

var cat = this.Category
Run Code Online (Sandbox Code Playgroud)

在Forum类的TopicChanged方法的底部,不再有任何错误.

我在这里做了一些完全错误的事情,我是否遇到过边界问题,或者发生了什么?我想EF会看到引用是一个延迟加载的引用,如果它没有被更改,没有理由为什么这应该保存失败???

谢谢,斯蒂恩

Ste*_*rup 8

我已经解决了我的问题.它可能不是一个非常好的和干净的解决方案,但至少我现在可以处理这种情况,而不必改变了很多我的代码(这需要与NHibernate也运行).所以没有脏解决方案.

只是为了让你了解它是如何解决的,我会试着在这里解释一下.

在我的存储库上的Commit()方法中,我开始在DbContext实例上调用GetValidationErrors().这将返回上面遇到的错误以及发生错误的实体.在这个实体的基本类型(实体是由EF生成的代理)上,我运行所有属性,当遇到具有Required属性的属性时,我在代理对象的相同属性上调用GetValue.

足够的谈话,更多的代码:

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)