已断开连接的dbcontext不会更新导航属性

时间:2014-04-11 20:31:06

标签: entity-framework asp.net-web-api dbcontext navigation-properties disconnected

我首先使用代码使用WebAPI 2.0和EF6.0编写API。 所以它必然是一个断开连接的dbcontext场景。

我的域名如下

public class Patient
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Email ( get; set; }
    public virtual Nutritionist Nutritionist { get; set; }
}

public class Nutritionist
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual List<Patient> Patients { get; set; }
}

用户界面将允许患者选择不同的营养师,如果她对当前的营养师不满意。所以我的API需要支持这一点。我推测这将是对患者的简单更新。但是单元测试失败了。

    [TestMethod]
    public void Changing_Nutritionist_In_Disconnected_Context_Works()
    {
        Patient p;
        Nutritionist n;
        using (var c = new Context())
        {
            // Get a patient where I know p.Nutritionist.Id == 1 in database.
            p = c.Patients.Find(1);

            // Get some other nutritionist
            n = c.Nutritionists.Find(3);
        }
        using (var c = new Context())
        {
            //change patient's email and nutritionist 
            p.Email = "patient@domain.com";
            p.Nutritionist = n;

            c.Patients.Attach(p);
            c.Entry(p).State = EntityState.Modified;
            c.SaveChanges();
        }
        using (var c = new Context())
        {
            Assert.AreEqual(3,c.Patients.Find(1).Nutritionist.Id);
        }
    }

我希望SaveChanges()可以保存患者p.Emailp.Nutritionist两个属性的更改。但是在数据库中,只有电子邮件被更改,Nutritionist_Id字段继续显示旧值。因此,由于某种原因,dbContext忽略了对导航属性p.Nutritionist

的更改

SQL分析器显示由EF

触发的以下UPDATE查询
exec sp_executesql N'UPDATE [dbo].[Patients]
SET [Name] = @0, [Email] = @1
WHERE ([Id] = @2)
',N'@0 nvarchar(max) ,@1 nvarchar(max) ,@2 int',@0=N'some name',@1=N'patient@domain.com',@2=1
go

不知道我可能错过了什么。

1 个答案:

答案 0 :(得分:2)

是的我可以使用显式属性p.NutritionistId,但我只是想成为纯粹主义者:)

我发现以下代码有效......

cn.Patients.Attach(p);
cn.Nutritionists.Attach(n);
cn.Entry(p).Reference(x => x.Nutritionist).Load();
p.Nutritionist = n;
cn.Entry(p).State = EntityState.Modified;
cn.SaveChanges();

在这种情况下,EF似乎不会自动附加相关条目... p.Nutritionist

同样如上面评论中提到的Gert Arnold,也没有加载它。

因此明确加载p.Nutritionist然后使用附加实体更改其值会使EF感到高兴。

我仍然想知道为什么EF不会自行完成所有这些,因为它似乎是一个逻辑编程意图,当我附加一个新实体并将其标记为EntityState.Modified时,我想要保存整个它而不仅仅是标量属性。