【问题标题】:EntityFramework LazyLoading SaveChanges BugEntityFramework LazyLoading SaveChanges 错误
【发布时间】:2014-04-11 01:13:01
【问题描述】:

例如。有一个名为 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()时它会抛出异常

【问题讨论】:

  • 您正在从数据库中获取实体 A,然后编辑 name 属性,然后尝试保存。在这两种情况下,您从数据库中获取的实体 A 的数据库是否完整?
  • 是的,它们完好无损。而且这个异常抛出没有规律。但是如果一个方法抛出异常,它总是会抛出异常。

标签: entity-framework lazy-loading


【解决方案1】:

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

因此,在您的第一个示例中,您从未加载过 B,因此您会遇到异常。在第二个示例中,您确实引用了B,这意味着对数据库的另一个调用,并且它被加载了。

您需要调用Include 来预加载B。不幸的是,您不能将IncludeFind 一起使用,因此请尝试以下方法:

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

【讨论】:

  • 那会破坏延迟加载的目的。如果B 也有C 的外键呢?您最终会不必要地加载所有依赖项。
  • 我使用DbSet从数据库中加载A,我也从数据库中加载B。然后我更改NameASaveChanges(),它会成功。这意味着对于属性BA 有一个keyB。换句话说,我保存A,EF 应该检查属性B 是否具有值或key。我认为这是真正的延迟加载。
  • 我的意思是我从数据库加载A,我不需要从数据库加载'B'。但是 EF 不允许我在未加载 B 的情况下进行保存。但是当我加载A 时,它也会加载keyB。为什么 EF 没有检测到这个key
  • 我不知道你的意思是它正在加载keyB 在被引用或急切加载之前将为空。
  • 我的意思是 EF 让一个类继承 A。并制作一些功能,例如名为_B 的字段,类型为Guid(如果B 类型的键为Guid)。当我加载A 时,_B 将给出一个值,它是属性B 的键。而如果EF有_B,为什么EF需要B有参考。
【解决方案2】:

我检查了实体框架的源代码。我发现错误的原因是关于ValidationAttributeValidator EF 程序集类的Validate 方法。

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

所以,我认为解决方案是更改ValidationAttributeValidator 类的Validate 方法的代码。如果 AttributeRequiredAttribute 则忽略它,并通过延迟加载来验证属性。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-05
    • 1970-01-01
    相关资源
    最近更新 更多