在Entity Framework中更新嵌套对象

8
最近我发现EF不会更新嵌套对象。几天来,我一直在尝试解决这个问题,但很遗憾我卡在了这个问题上。
我有一个对象:
public class ProjectEntity : AuditableEntity<int>
{

    public string CustumerCompany { get; set; }
    public string CustomerRepresentative { get; set; }

    public string ProjectTitle { get; set; }
    public string WwsNumber { get; set; }

    [ForeignKey("ParentProjectId")]
    public virtual ProjectEntity ParentProject { get; set; }

    public int? ParentProjectId { get; set; }

    public virtual ICollection<ProjectServicesEntity> Service { get; set; }
}

然后是服务对象。
public class ProjectServicesEntity : AuditableEntity<int>
{
    /// <summary>
    /// Service Number
    /// </summary>
    public int Number { get; set; }
    /// <summary>
    /// Service Name
    /// </summary>
    public string Name { get; set; }

    /// <summary>
    /// Positions
    /// </summary>
    public virtual ICollection<ProjectPositionsEntity> Positions { get; set; }

    [ForeignKey("ProjectId")]
    public virtual ProjectEntity Project { get; set; }

    public int ProjectId { get; set; }
}

和Positions对象:

public class ProjectPositionsEntity : AuditableEntity<int>
{
    /// <summary>
    /// Position number
    /// </summary>
    public int Number { get; set; }

    /// <summary>
    /// Position Name
    /// </summary>
    public string Name { get; set; }

    /// <summary>
    /// Organization Unit for position
    /// </summary>
    public virtual ICollection<ProjectsOutsourcedPositionEntity> OrganizationUnit { get; set; }
    /// <summary>
    /// Represents if position is outsourced
    /// </summary>
    public bool OutSource { get; set; }
    /// <summary>
    /// Comments for position
    /// </summary>
    public string Remarks { get; set; }

    [ForeignKey("ServiceId")]
    public virtual ProjectServicesEntity Service { get; set; }

    public int ServiceId { get; set; }

}}

我的更新方法:

public void Update(T entity)
    {

            DbContext.Entry(entity).State = EntityState.Modified;
            DbContext.SaveChanges();
}

当页面上显示所有数据时,当我尝试在服务或职位中编辑某些数据时,它不会更新。有人遇到过这种问题吗?
我看到的每个示例都只有一个嵌套对象,深度为1级,但是如您所见,我的对象有2级嵌套。

你确定你的页面上的更改已经到达了服务器吗?如果你在测试工具(控制台应用程序)中尝试,它是否表现相同?例如,编写一个小型控制台应用程序,加载一些数据并更改对象,然后保存。保存是否成功? - Adam Benson
我猜你是在谈论断开的对象。这从未被Entity Framework解决过,你可以看一下GraphDiff包。 - Ivan Stoev
@AdamBenson 是的,我确定。问题在于EF只会更新标记为Modified的EF对象,而这种状态不适用于子对象。因此,我需要为它们设置修改状态。 我发布了我的解决方案。 - Daniil T.
1个回答

6

所以我想出了如何让它工作。

在具体的存储库类中,我使用了几个foreach循环将实体状态设置为已修改。根据我们的业务规则,项目需要有服务、职位和组织单位,而对于职位来说,组织单位是可选的,因此我检查了它是否为null。

这是我的解决方案:

DbContext.Entry(entity).State = EntityState.Modified;
            foreach (var service in entity.Service)
            {
                DbContext.Entry(service).State = EntityState.Modified;
                foreach (var position in service.Positions)
                {
                    DbContext.Entry(position).State = EntityState.Modified;
                    if (position.OrganizationUnit == null) continue;
                    foreach (var organizationUnit in position.OrganizationUnit)
                    {
                        DbContext.Entry(organizationUnit).State = EntityState.Modified;
                    }
                }
            }
            DbContext.SaveChanges();

现在,当我想要在任何级别上更新我的对象时,它会更新到我的数据库中。

你如何跟踪第2和第3级别的已删除项目? - Jacques
基本上和我修改它们的方式相同。 - Daniil T.
我又回到了这个问题。我将一个包含OrderItems的Order传递到Angular项目中,用户可以删除单个OrderItems,然后点击保存。我的做法是将已经删除OrderItems的Order发送回服务器。但EFC没有做任何事情,所以我猜那些已删除的OrderItems应该被保留在那里,并标记为已删除? - Jacques
@Jacques 如果没有看到你的代码,很难发表意见。你能分享一下你的代码让我看看吗? - Daniil T.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接