1

個別に回答できる質問が 2 つあります。

Q#1

データベース サーバーへのラウンド トリップを保存しようとしています。

ここに私のアルゴリズムがあります:

  1. 2 つのエンティティを挿入します (データベースによって生成された ID を取得するため)
  2. 返された ID を使用して、ID を渡すストアド プロシージャを呼び出します。

ストアド プロシージャは 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();
}

したがって、次のコードのように行われた「ADD」に対してEntityState.Addedを検出できる方法があるかどうか疑問に思っていました。

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() を呼び出した後、データベースへの同じ「トリップ」の一部としてストアド プロシージャを呼び出す方法はありますか?

4

1 に答える 1

1

質問1

エンティティの状態は、次の方法で検出できます。

db.Entry(robot).State

ラインの後

skyNet.Robots.Add(robot);

EntityStaterobotなりますAdded。ただし、疑似コードでは、skyNet変数がどこから来たのか明確ではありません。コードスニペットで行うようにを追加すると、次のskyNetことができます。

foreach( 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);
    }
}

質問2

NHibernate のマルチ クエリのようなものが必要になるため、1 回のラウンドトリップでストアド プロシージャを呼び出すことはできません。ただし、次を使用して、ストアドプロシージャ呼び出しを1つのトランザクションでラップできますSaveChanges(これがあなたの意図だと思います) TransactionScope

using (TransactionScope scope = new TransactionScope())
{
    // stored procedure call here.
    db.SaveChanges();
    scope.Complete();
}
于 2013-05-09T21:38:08.780 に答える