2

我正忙于使用 MVC4 开发一个 ASP.net Web 应用程序,并在尝试将一些更改保存到数据库时遇到了这个奇怪的错误。这段代码在我的一个控制器中。下面的代码在调用 _db.Save() 时会导致 DbEntityValidationException,而 _db.Save() 又会调用 SaveChanges()。我正在使用 EntityFramework V5。

Document document = _db.Documents.SingleOrDefault(x => x.ID == doc.ID);
if (document != null)
{
    document.Location = idPath;
    _db.Save();
}

异常消息:

在此处输入图像描述

但是:当我使用以下代码时,我没有任何异常,并且路径成功保存到数据库。

Document document = _db.Documents.FirstOrDefault(x => x.ID == doc.ID);
if (document != null)
{
    // Needed for SaveChanges to work
    var x = document.Type;

    document.Location = idPath;
    _db.Save();
}

为什么会发生这种情况?可能是因为我的 Documents 集合是 List 类型的吗?请注意,我发现错误是由 Type 属性引起的。

下面是我的 Document 类的结构:

[Table("Document")]
public class Document
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public virtual int ID { get; set; }

    [Required]
    public virtual string Name { get; set; }
    public virtual string Location { get; set; }
    [Required]
    public virtual DocumentType Type { get; set; }

    [NotMapped]
    public virtual HttpPostedFileBase File{ get; set; }
}
4

2 回答 2

2

public virtual DocumentType Type根据您的实体定义是必需的,但是在您的第一个示例中,Type如果未启用急切加载(这是我的假设),它将为空。

您的第二个示例有效的原因是因为Type在此行上被延迟加载var x = document.Type;。您可以打开即时加载,也可以使用.Include()选择性地加载Type属性。

查看此链接以获取有关各种类型的 EF 加载相关实体的信息。

http://msdn.microsoft.com/en-us/data/jj574232.aspx

于 2013-08-12T17:25:33.087 回答
2

我认为问题是因为Lazy Loading.

事实上,通过调用这一行:

Document document = _db.Documents.SingleOrDefault(x => x.ID == doc.ID);

您只获得Document实体的标量属性,其导航属性保持为空......!(设置断点并查看)。

但是,当您调用此行时:

var x = document.Type;

您强制 EF 查询数据库以将Type导航属性提取到内存中并将其附加到 dbcontext。确实这是一种正常行为,延迟加载!- 除非真的需要,否则不要得到任何东西。

所以,如您所见,这当然不是一个奇怪的错误!这只是延迟加载的副作用......

于 2013-08-12T17:45:12.590 回答