在Entity framework 4.1 (CodeFirst)中更新对子对象的引用

本文关键字:更新 对象 引用 framework Entity CodeFirst | 更新日期: 2023-09-27 18:12:03

我正在尝试更新一个对象,我以前保存的EntityFramework 4.1 (CodeFirst)

Job类有以下属性…

public class Job
{
    [key]
    public int Id { get; set; }
    public string Title { get; set; }
    public Project Project { get; set; }
    public JobType JobType { get; set; }
    public string Description { get; set; }
}

最初的创建工作正常,但更新只提交更改到字符串..

如果我更改子对象,例如将JobType属性从JobTypeA更改为JobTypeB -更改不会提交…

我不打算修改JobType,只修改Job。

using (var context = new JobContext())
{
    context.Jobs.Attach(job);
    context.Entry(job).State = EntityState.Modified;
    context.SaveChanges();
}

看看SQL Profiler - id甚至没有被发送到更新-但是它们是用于初始插入的!

在Entity framework 4.1 (CodeFirst)中更新对子对象的引用

将状态设置为Modified只更新标量和复杂属性,而不是导航属性。这只需要通过实体框架的变更检测。这意味着您需要从数据库加载原始文件:

using (var context = new JobContext())
{
    var originalJob = context.Jobs.Include(j => j.JobType)
        .Single(j => j.Id == job.Id);
    // Update scalar/complex properties
    context.Entry(originalJob).CurrentValues.SetValues(job);
    // Update reference
    originalJob.JobType = job.JobType;
    context.SaveChanges();
}

在这种情况下,您可能还可以利用一些"技巧":

using (var context = new JobContext())
{
    var jobType = job.JobType;
    job.JobType = null;
    context.JobTypes.Attach(jobType);
    context.Jobs.Attach(job);
    // change detection starts from here,
    // EF "thinks" now, original is JobType==null
    job.JobType = jobType;
    // change detection will recognize this as a change
    // and send an UPDATE to the DB
    context.Entry(job).State = EntityState.Modified; // for scalar/complex props
    context.SaveChanges();
}

如果你想将JobType设置为null,它将不起作用。

这是一种典型的情况,如果你将外键暴露为模型中的属性,它会变得简单得多:在你的Job实体中使用JobTypeId,你的代码将工作,因为FK属性是标量,并且将状态设置为Modified也会将该属性标记为修改。