【问题标题】:Entity framework 6.0 : How can i ensure transactional integrity between two entities where one need assigned Id of the other entity?实体框架 6.0:如何确保两个实体之间的交易完整性,其中一个实体需要分配另一个实体的 ID?
【发布时间】:2016-03-08 22:59:15
【问题描述】:

我已经看到很多关于在事务中多次调用 dbContext.SaveChanges 的问题和建议。 有人说应该避免这种情况。这篇深度文章真的值得一读http://mehdi.me/ambient-dbcontext-in-ef6/

在我的特定场景中,实体 B 具有对实体 A 的 Id 引用

在创建场景期间,我创建 A 并调用 savechanges 以获取数据库分配的 A.Id。 然后我像 new B(A.Id,....) 一样创建实体 B 并再次调用 savechanges。在伪代码中可能看起来像这样

using(var tx =  dbContext.BeginTransaction())
{
    var a = new A();
    dbContext.Add(a);  //a.Id is null
    dbContext.saveChanges(); // a.Id has now been initialized

    var b = new B(a.Id); //I want to create b in a valid state so a.Id  cannot be null
    dbContext.SaveChanges();
    tx.Commit();
}

(我知道伪代码缺少异常处理逻辑……)

为什么会出现这个问题? 是不是因为savechanges不能回滚?

我知道我可以改造,但这是不可能的,因为我们与一些遗留系统共享数据库,所以数据库不能轻易更改,如果可能的话!

什么是替代解决方案?

【问题讨论】:

  • 鉴于 Entity Framework 确实支持显式事务,问题是什么?您似乎为您似乎错过的功能编写伪代码,而您的伪代码实际上调用了一个存在的方法。你打扰文档了吗? msdn.microsoft.com/en-us/data/dn456843.aspx 标题为“使用事务(从 EF6 开始)”。
  • SaveChanges 使用内部事务。更改分配是已经原子的。实际的问题是什么?仅仅因为有人在某处写了您应该多次致电SaveChanges 并不意味着它是正确的。事实上,为什么你的代码会调用它两次??。
  • 如果您使用适当的关系,则没有理由分配 ID。 EF 将识别新的/修改的类并生成 SQL 语句,以正确的顺序插入新对象
  • 感谢 cmets。是的,我已阅读有关交易的文章。在某些情况下,我可能更喜欢仅通过 Id 引用而不具有对象关系。我的代码第一次调用 SaveChanges 以获取 A 的 ID,以便我可以初始化 B。我有两个问题:1)我不清楚为什么调用 savechages 两次是不好的。 2)解决问题的替代方法。我很欣赏你提出的建议..

标签: c# entity-framework transactionscope


【解决方案1】:

像这样使用navigation property

public class A
{
    [Key]
    public int Id { get; set; }

    public int BId { get; set; }

    [ForeignKey("BId")]
    public B B { get; set; }
}

public class B
{
    [Key]
    public int Id { get; set; }
}

然后简单地将新创建的B 分配给A 的导航属性:

using (var transaction = dbContext.BeginTransaction())
{
    var a = new A();
    a.B = new B();
    dbContext.Add(a);
    dbContext.saveChanges();
    transaction.Commit();
}

【讨论】:

  • SaveChanges 已经使用了一个事务。除此之外,使用导航属性是处理关系的正确方法
  • @PanagiotisKanavos:正确 - 只是想保持代码类似于 OP“伪代码”:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-22
  • 2021-07-04
相关资源
最近更新 更多