EntityFramework LazyLoading SaveChanges Bug

时间:2014-04-07 11:17:54

标签: entity-framework lazy-loading

例如。有一个名为A的课程。

public class A
{
    [Key]
    [Required]
    public virtual Guid Id {get;set;}
    [Required]
    public virtual string Name {get;set;}
    [Required]
    public virtual B B {get;set;}
}

当我调用此方法时,它将抛出B不能为空的异常。

public void Edit(Guid id, string name)
{
    A a = _DbSet.Find(id);
    a.Name = name;
    _DbContext.SaveChanges();
}

但这会成功。

public void Edit(Guid id, string name)
{
    A a = _DbSet.Find(id);
    a.Name = name;
    B b = a.B; 
    _DbContext.SaveChanges();
}

这是实体框架的错误吗?

我在版本6.1中使用它。

====================================

我发现一个常规的例子,如果属性链接到实体并且它没有从数据库加载,那么当你调用SaveChanges()时它会抛出异常

2 个答案:

答案 0 :(得分:0)

这不是一个错误 - 它是一个功能!您已将B指定为Required,但也指定virtual,这意味着它将被延迟加载 - 换句话说,在您引用它之前,它不会被加载。

所以在你的第一个例子中,你永远不会加载B,所以你得到了例外。在第二个示例中,您引用B,这意味着对数据库的另一次调用,并且它被加载。

您需要致电Include以急切加载B。很遗憾,您无法将IncludeFind一起使用,因此请尝试以下方式:

A a = _DbSet.Include("B").SingleOrDefault(a => a.id == id);

答案 1 :(得分:0)

我查看了Entity Framework的源代码。我发现bug的原因是关于Validate类EF汇编的ValidationAttributeValidator方法。

当一个实体要验证时调用此方法。它会检查Attribute的任何Property。但是,RequiredAttribute不属于EF程序集。 GetValidationResult的{​​{1}}方法不关心延迟加载EF。

所以,我认为解决方案是更改RequiredAttribute类的Validate方法的代码。如果ValidationAttributeValidatorAttribute,请忽略它,并使用延迟加载来验证属性。