拦截ADD以通过Entity Framework 5中的集合检测它是否是ADD

时间:2013-05-09 18:45:20

标签: entity-framework-5

我有两个问题可以单独回答。

问题#1

我正在尝试保存到数据库服务器的往返行程。

这是我的算法:

  1. 插入2个实体(以获取数据库生成的ID)
  2. 使用返回的ID调用存储过程传递ID
  3. 存储过程获取ID并填充一个邻接列表表,我用它来存储有向非循环图。

    目前,我为每个父子关系进行了RDBMS的往返,加上一个用于实体的插入。

    我知道做这样的事情:

    public override int SaveChanges()
    {
        foreach (var entry in this.ChangeTracker.Entries().Where(e => e.State == System.Data.EntityState.Added).ToList())
        {
            if (entry.Entity is IRobot)
            {
                entry.Reference("Owner").CurrentValue = skyNet;
            }
        }
    
        return base.SaveChanges();
    }
    

    所以我想知道是否有一种方法可以检测到 EntityState.Added 的“ADD”,类似于以下代码:

    var robot = new Robot(); 
    skyNet.Robots.Add(robot); 
    db.Add(skyNet); 
    db.SaveChanges();
    

    这样我可以这样做:(注意这是伪代码)

    public override int SaveChanges()
    {
        foreach (var entry in this.ChangeTracker.Entries().Where(e => e.State == EntityState.**AddedToCollection**).ToList())
        {
            db.Relate(parent: skyNet, child: entry.Entity);
        }
    
        return base.SaveChanges();
    }
    

    Q#2

    在调用SaveChanges()后,无论如何调用存储过程作为数据库相同“行程”的一部分?

1 个答案:

答案 0 :(得分:1)

问题1

您可以通过

检测实体的状态
db.Entry(robot).State

行后

skyNet.Robots.Add(robot);

EntityState的{​​{1}}将为robot。但是,在您的伪代码中,不清楚Added变量的来源。如果您在代码段中添加skyNet,则可以执行以下操作:

skyNet

问题2

您无法在一次往返中调用存储过程,这需要像NHibernate的多查询一样。但是,您可以使用TransactionScopeforeach( var skyNet in ChangeTracker.Entries() .Where(e => e.State == EntityState.Added) .Select (e => e.Entity) .OfType<SkyNet>()) { foreach(var robot in skyNet.Robots .Where(r => db.Entry(r).State == EntityState.Added)) { db.Relate(parent: skyNet, child: robot); } } 和存储过程调用包装在一个事务中(我认为这就是您的意思):

SaveChanges