gpt4 book ai didi

c# - 在断开连接的环境 (EF) 中使用 Db 生成的 ID 更新实体图 ID

转载 作者:行者123 更新时间:2023-11-30 16:10:49 25 4
gpt4 key购买 nike

我正在使用 EF6 code firstWinForm项目。我使用以下方法从 Db 中读取实体,更新它们,然后将它们保存回 Db :

  1. 使用 Linq to entities 读取实体图(阅读DbContext后处理)
  2. 显示已读Entity给最终用户的图表。
  3. 最终用户可以将此更改应用于 Entity图形:
    • 更新根实体
    • 添加一些子实体
    • 编辑一些子实体
    • 删除一些子实体
  4. 用户调用一个方法来保存他对 Db 的更改
  5. 创建一个新的 DbContext实例。
  6. 重新加载相同的 Entity图表来自 Db
  7. 使用 AutoMapper 将所有属性的值从用户实体映射到重新加载的实体
  8. 将6步的结果实体附加到我的DbContext使用 GraphDiff
  9. 调用 DbContext.SaveChanges();保留对 Db 的更改 enter image description here

    var root = new MyDbcontext()
    .Roots
    .LoadAggregation()
    .ToList();
    // LoadAggregation in this case, means following codes:
    // .Include("Child1")
    // .Include("Child2")

    root.Child1s.Remove(child11);
    root.Child1.Add(Child13); //
    root.Child2.Add(Child22);
    using(var uow = new UnitOfWork())
    {
    uow.Repository<Root>().Update(root);
    uow.Repository<AnotherRoot>().Update(anotherRoot); //user may want to update multiple Roots
    uow.SaveChanges(); <---- at this point Child13.Id and Child22.Id generated by Db
    }

    public void Update(Root entity) //Update method in my Repository class
{
var context = new MyDbcontext();
var savedEntity = context.Roots //reload entity graph from db
.LoadAggregation()
.ToList();
Mapper.Map(entity,savedEntity); // map user changes to original graph
context.UpdateGraph(savedEntity, savedEntity.MappingConfiguration); // attach updated entity to dbcontext using graphdiff
}

    public void SaveChanges() // SaveChanges() in UnitofWork class
{
context.SaveChanges();
}

工作正常,

在第二张图中,用户添加了 Child13 和 Child22,当我调用 uow.SaveChanges() 时他们将保存到 Db和他们的 Id s 将被分配。但是Child13.IdChild22.Identity对象是 0然而,我可以手动更新 Id s 但我正在寻找通用 方式来更新这些 Id Db 的值生成 Id

最佳答案

就我个人而言,我会采取稍微不同的方法。

像这样的事务不应跨越多个上下文。即使您可以手动更新这些 ID,您也需要某种替代方法来识别这些子对象,以确保您将对象实例与数据库分配的 ID 正确同步。或者这些对象的其他方面可能在瞬时更新,并且也需要应用于数据库。一般来说,从不同的 DBContext 加载的对象是不同的对象,即使它们具有相同的数据库标识,除非您已经在 EF 之上实现了某种缓存。

我会做这样的事情。使用一个上下文,并让 EF 通过在需要执行持久性操作的地方注入(inject)上下文来为您管理所有标识:

var context = new MyDbcontext();
var root = context
.Roots
.LoadAggregation()
.ToList();
// LoadAggregation in this case, means following codes:
// .Include("Child1")
// .Include("Child2")

root.Child1.Remove(child11);
root.Child1.Add(Child13); //
root.Child2.Add(Child22);
using(var uow = new UnitOfWork())
{
uow.Repository<Root>().Update(root, context);
uow.Repository<AnotherRoot>().Update(anotherRoot, context); //user may want to update multiple Roots
uow.SaveChanges(context); <---- at this point Child13.Id and Child22.Id generated by Db
}

public void Update(Root entity, MyDbcontext context) //Update method in my Repository class
{
var savedEntity = context.Roots //reload entity graph from db
.LoadAggregation()
.ToList();
Mapper.Map(entity,savedEntity); // map user changes to original graph
context.UpdateGraph(savedEntity, savedEntity.MappingConfiguration); // attach updated entity to dbcontext using graphdiff
}

public void SaveChanges(context) // SaveChanges() in UnitofWork class
{
context.SaveChanges();
}

如果由于某种原因您无法使用相同的上下文,您可能需要考虑向子对象添加某种额外的标识字段,例如 Guid,并在返回之前将其写入子对象通过 SaveChanges 到数据库。至少您可以通过一种相当一致的方式来识别要同步的对象。

关于c# - 在断开连接的环境 (EF) 中使用 Db 生成的 ID 更新实体图 ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25154882/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com