0

我有一个File实体和一个User实体。实体通过一个名为的属性与File实体具有 1:1 的关系(这记录了上次更改文件的用户)。在名为 的实体中还有一个字段,它是实际的 FK 关系。这种关系是单向的:实体没有返回实体的导航属性。UserLastChangeUserFileLastChangeUserIdUserFile

class File
{
    public int Id { get; set; }

    public int? LastChangeUserId { get; set; }
    public virtual User LastChangeUser { get; set; }
}

class User
{
    public int Id { get; set; }
}

当 aFile改变时,我需要LastChangeUserFile. 我只有用户的 ID,而不是完整的 User 对象。所以,我正在这样做:

file.LastChangeUser = null;
file.LastChangeUserId = userId;

File当新创建对象(然后将其添加到实体集合中的 POCO)时,这似乎适用于创建文件。

File但是,当对象是从数据库中检索(作为代理)的现有对象时,更新文件时它不起作用。

在后一种情况下,我最终在数据库中为该LastChangeUserId字段设置了一个 NULL。(调用 SaveChanges 后,该对象nullLastChangeUserLastChangeUserId字段中都有)。

也许我在这里做错了?什么是正确的方法?我真的需要去获取User对象才能设置LastChangeUser属性吗?

4

1 回答 1

1

@kevin_fitz 解决方案在这里工作的原因是由于 EF 工作中的变更跟踪和验证方式。EF 中更改跟踪的默认行为是一种称为快照跟踪的方法,该方法实质上是在每个实体首次加载时克隆其初始状态。当您在 EF 中保存更改时,会将每个实体的原始快照与当前状态对象(您正在修改的对象)进行比较,并将任何差异保存到数据库中。

除此之外,此 EF 还对实体执行提交前验证(仅供参考)。

在您的情况下,您对模型进行了两项更改,快照跟踪器将在保存时检测到这些更改(它们实际上是冲突的)。然而,跟踪器将尝试通过验证规则处理这两个,这将表明这是一个必需的关系并且不能设置为 null。这就是您看到此错误的原因以及为什么删除 null 更新可以解决您的问题。

在旁注中,您实际上只需要更新导航属性上的对象或键即可触发要更新的数据库关系。有关导航属性如何在 EF codefirst 中工作的更多详细信息,请查看我的文章:http: //blog.staticvoid.co.nz/2012/07/entity-framework-navigation-property.html

于 2012-10-14T02:43:03.513 回答