c# - 如何使用 Entity Framework 更新自引用图?

标签 c# entity-framework graph sql-update

我正在使用 Entity Framework 来处理数据库,并且我有如下自引用模型:

public class PhysicalObject
{
    public PhysicalObject()
    {
        SubPhysicalObjects = new HashSet<PhysicalObject>();
    }

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    public int? ParentId { get; set; }

    [StringLength(150)]
    public string Title { get; set; }

    public virtual PhysicalObject Parent { get; set; }

    public virtual ICollection<PhysicalObject> SubPhysicalObjects { get; set; }

}

我正在使用 GraphDiff 库来更新断开连接的图,但它似乎不支持更新自引用图。

我的问题是:使用 Entity Framework 更新自引用图的最佳方式是什么:

  • 删除/更新现有的物理对象

  • 插入不存在的物理对象

最佳答案

假设我有两个实体如下:

public class PhysicalObject
{

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    public int? ParentId { get; set; }

    public int StorageRequestId { get; set; }

    public string Title { get; set; }

    public virtual PhysicalObject Parent { get; set; }

    public virtual ICollection<PhysicalObject> SubPhysicalObjects { get; set; }

    public virtual StorageRequest StorageRequest { get; set; }

}

public class StorageRequest
{
    public StorageRequest()
    {
        PhysicalObjects = new HashSet<PhysicalObject>();
    }

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    public string Title { get; set; }

    public virtual ICollection<PhysicalObject> PhysicalObjects { get; set; }
}

注意 PhysicalObject 是自引用表。

不要让我们使用 Entity Framework 更新图表:

 var oldPhysicalObjects = dbContext.PhysicalObjects.Where(x => x.StorageRequestId== storageRequestId).ToList();

 var existingIds = new HashSet<int>();
 foreach (var item in newGraphDto.PhysicalObjects.ToList())
   {
     updateGraph(item, oldPhysicalObjects, dbContext, storageRequestId,existingIds);
   }
 var posToDelete = oldPhysicalObjects.Where(x => existingIds.All(e => e != x.Id)).ToList();
 dbContext.PhysicalObjects.RemoveRange(posToDelete);
 dbContext.SaveChanges();

updateGraph 方法将递归更新每棵 PhysicalObjects 树,它看起来像:

private void updateGraph(PhysicalObjectDto physicalObjectDto, IList<PhysicalObject> oldPhysicalObjects, MyDbContext dbContext, int storageRequestId, HashSet<int> existingIds, PhysicalObject parent = null)
    {
        if (physicalObjectAddEditDto.Id == 0)
        {
            PhysicalObject po = new PhysicalObject
            {
                Id = physicalObjectAddEditDto.Id,
                Title = physicalObjectAddEditDto.Title,
                StorageRequestId = storageRequestId,
                Parent=parent

            };

            dbContext.PhysicalObjects.Add(po);

            parent = po;
        }
        else
        {
            var po = oldPhysicalObjects.FirstOrDefault(x => x.Id == physicalObjectAddEditDto.Id);
            po.Title = physicalObjectAddEditDto.Title;
            po.StorageRequestId = storageRequestId;
            po.Parent = parent;
            dbContext.Entry(po).CurrentValues.SetValues(po);

            parent = po;
        }


        existingIds.Add(parent.Id);
        foreach (var subPhysicalObject in physicalObjectAddEditDto.SubPhysicalObjects)
        {
            updateGraph(subPhysicalObject, oldPhysicalObjects, dbContext, mailRoomRequestId, existingIds, parent);
        }

    }

我希望我的代码能帮助其他人知道如何更新自引用表的图树

关于c# - 如何使用 Entity Framework 更新自引用图?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47616604/

相关文章:

c# - Wpf TreeView 分组

c# - ASP.NET Web Api 2 通过 Id 获取

c# - asp.net中的类库和静态变量

java - 我是否可以使用多对多关系在另一个实体上拥有实体集合?

java - 关于如何使用 A* 解决 Java 中的尖峰时刻谜题并获得最低移动次数的指南。需要有关如何开始和遵循的步骤的帮助

c# - Doxygen:不支持部分类?

c# - 基于 EF 4.0 泛型的继承

asp.net-mvc - 通过 OData 和 WebAPI 公开大数据模型

r - 如何在r中重叠更多图形

algorithm - 在具有多维前置数组的图中查找两个节点之间的所有最短路径