令人沮丧的这是由数据库优先 Entity Framework 生成的一对相关对象:

public partial class DevelopmentType
{
    public DevelopmentType()
    {
        this.DefaultCharges = new HashSet<DefaultCharge>();
    }

    public System.Guid RowId { get; set; }
    public string Type { get; set; }

    public virtual ICollection<DefaultCharge> DefaultCharges { get; set; }
}

public partial class DefaultCharge
{
    public System.Guid RowId { get; set; }
    public decimal ChargeableRate { get; set; }
    public Nullable<System.Guid> DevelopmentType_RowId { get; set; }

    public virtual DevelopmentType DevelopmentType { get; set; }
}

这是我用来保存DevelopmentType的代码-它涉及自动映射器,因为我们将实体对象与DTO区分开来:
    public void SaveDevelopmentType(DevelopmentType_dto dt)
    {
        Entities.DevelopmentType mappedDevType = Mapper.Map<DevelopmentType_dto, Entities.DevelopmentType>(dt);
        _Context.Entry(mappedDevType).State = System.Data.EntityState.Modified;

        _Context.DevelopmentTypes.Attach(mappedDevType);
        _Context.SaveChanges();
    }

在我的用户界面中,最常见的操作是使用户查看DevelopmentTypes列表并更新其DefaultCharge。因此,当我使用上面的代码进行测试时,它可以正常运行,但实际上没有任何变化。

如果我在调试器中暂停,很明显更改后的DefaultCharge将传递到函数中,并将其附加到要保存的DevelopmentType中。

逐步执行,如果我在Visual Studio中手动更改值,它将保存更新的值。这更令人困惑。

使用SQL Server Profiler监视数据库显示,更新命令仅针对父对象而不针对任何附加对象发出。

我在其他地方有其他类似的代码,可以正常运行。我在这里做错了什么?

编辑:

我发现,如果在调用SaveDevelopmentType之前执行此操作,则:
        using (TransactionScope scope = new TransactionScope())
        {
            dt.Type = "Test1";
            dt.DefaultCharges.First().ChargeableRate = 99;
            _CILRepository.SaveDevelopmentType(dt);
            scope.Complete();
        }

保存对类型的更改,但不保存对ChargeableRate的更改。我认为这没有太大帮助,但我想添加一下。

最佳答案

问题是,EF无法识别已更改的DefaultCharges。

通过将DevelopmentType的状态设置为EntityState.Modified,EF仅知道对象DevelopmentType已更改。但是,这意味着EF仅更新DevelopmentType,而不会更新其导航属性。

一种解决方法-不是最佳实践-将遍历当前DefaultCharge的所有DevelopmentType并将实体状态设置为EntityState.Modified

另外,我建议先将实体附加到上下文,然后再更改状态。

评论后编辑

在使用DTO时,我想您正在通过不同的层或不同的机器传输这些对象。

在这种情况下,我建议使用自我跟踪实体,因为不可能共享一个上下文。这些实体还保持其当前状态(即,新的,更新的,删除的等)。网上有很多关于自我跟踪实体的教程。

例如MSDN - Working with Self-Tracking Entities

关于c# - Entity Framework 不保存修改后的子代,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18054798/

10-13 07:59