0

基本的に、エンティティ フレームワークでこの一連のイベントを実行しようとしています。

  1. 新しいアカウントを作成する
  2. 既存のアカウントを取得する
  3. すべてのデータを古いアカウントから新しいアカウントに移動します (トランザクション、ユーザーなど)
  4. 古いアカウントを削除する

単一の ObjectContext 内で、これをすべて「一度に」実行しています。

コンテキストで SaveChanges を呼び出すと失敗します。外部キー制約エラーが発生します。

これを SQL プロファイラーで確認したところ、エンティティ フレームワークが更新を送信しておらず、選択したものだけを送信してから削除したことがわかりました。

なぜそのように機能するのかはちょっと理解できますが、SaveChanges() を 2 回呼び出す必要なく、適切に機能させる方法が必要です。

うまくいけば。


私のマージ機能は基本的に次のようになります

public void Merge(Account newAccount, Account oldAccount)
{
    // ...

    foreach (var user in oldAccount.Users.ToList())
    {
        oldAccount.Users.Remove(user);
        newAccount.Users.Add(user);
    }

    // ...

    _unitOfWork.Accounts.Delete(oldAccount);
}      

オブジェクトは、EF4 POCO エンティティ ジェネレーターによって作成された POCO オブジェクトです。クラス全体を貼り付けるのを避けるために、'fixup' 機能を持つ関連付けプロパティの 1 つだけをここに示します。

public virtual ICollection<User> Users
{
    get
    {
        if (_users == null)
        {
            var newCollection = new FixupCollection<User>();
            newCollection.CollectionChanged += FixupUsers;
            _users = newCollection;
        }
        return _users;
    }
    set
    {
        if (!ReferenceEquals(_users, value))
        {
            var previousValue = _users as FixupCollection<User>;
            if (previousValue != null)
            {
                previousValue.CollectionChanged -= FixupUsers;
            }
            _users = value;
            var newValue = value as FixupCollection<User>;
            if (newValue != null)
            {
                newValue.CollectionChanged += FixupUsers;
            }
        }
    }
}   

private void FixupUsers(object sender, NotifyCollectionChangedEventArgs e)
{
    if (e.NewItems != null)
    {
        foreach (User item in e.NewItems)
        {
            item.Account = this;
        }
    }

    if (e.OldItems != null)
    {
        foreach (User item in e.OldItems)
        {
            if (ReferenceEquals(item.Account, this))
            {
                item.Account = null;
            }
        }
    }
}
4

2 に答える 2

0

オブジェクトを参照として使用して、 for ループ内で追加および削除します。これは、追加時にオブジェクトを使用する状態でオブジェクトをキーで取得するための最良のソリューションです。

 oldAccount.Users.Remove(user);
 newAccount.Users.Add(users.FirstOrDefault(t=>t.ID = user.Id));
于 2012-09-18T19:27:53.707 に答える
0

さて、解決策を考え出しました。@CodeGorilla さんのコメントがヒントになりました。

基本的に電話するしかない

_context.SaveChanges(SaveOptions.AcceptAllChangesAfterSave);

アカウントを削除しようとする前に。これにより、エンティティ フレームワークがデータベース内のすべての更新を実行するようになります。その後、削除しても問題ありません。

于 2012-09-19T08:31:58.850 に答える