4

トランザクション スコープで一連のデータベース更新をラップしようとしています。最初のデータベース更新は機能するが、2 回目は失敗するという問題がありました。DbContext を値でメソッドに渡していた支払いに関係していると思います...これは本質的に、呼び出されたメソッドでそのコピーを作成しています (右?)。そのため、これはトランザクションのコンテキストがそのまま残っていないという問題を引き起こしていたと思います...これは私の現在の理解レベルを少し上回り、学習しようとしていますが、これは現時点での私の推測です.

そのため、参照によって呼び出されたメソッドに DbContext を渡す必要があると思いましたが、ローカル変数の割り当てが正しくないという警告が表示されます。

では、サブメソッドを using ブロック内から呼び出すことでこのカプセル化を使用し、DbContext の整合性を維持するにはどうすればよいでしょうか?

これが私のラッパーメソッドです:

// define our transaction scope
                var scope = new TransactionScope(
                    // a new transaction will always be created
                    TransactionScopeOption.RequiresNew,
                    // we will allow volatile data to be read during transaction
                    new TransactionOptions()
                    {
                        IsolationLevel = IsolationLevel.ReadUncommitted
                    }
                );

                try
                {
                    // use the scope we just defined
                    using (scope)
                    {
                        // create a new db context
                        var ctx = new InventoryMgmtContext();
                        using (ctx)
                        {
                            //Initial count of rows in Alloc Needs
                            System.Diagnostics.Debug.WriteLine("Begin Alloc Need Recs: " + ctx.AllocationNeeds.Count().ToString());

                            //De-Allocate inventory container dtls
                            var deAllocInvenResult = DeAllocInvenForNeed(ref ctx, intFacilityId, needSourceType, intNeedSourceId, intUserId);

                            //Delete Allocation Need and Allocated Ctnr records
                            var deleteAllocNeedResult = DeleteAllocRecords(
                                ref ctx,
                                intFacilityId,
                                needSourceType,
                                intNeedSourceId
                            );

                            //var repository = new Repository<AllocationNeed>(ctx);


                        }
                        // everything good; complete
                        scope.Complete();
                    }

そして、更新を行うサブメソッドの 1 つを次に示します。

//Delete Allocation Need and AllocatedContainers for alloc need id
        private ActionConfirmation<int> DeleteAllocRecords(
            ref InventoryMgmtContext ctx,
            int intFacilityId,
            AllocationNeed.NeedSourceTypeOptions needSourceType,
            int intNeedSourceId
        )
        {
            var repository = new Repository<AllocationNeed>(ctx);

            //Delete Allocation Need and hence children in Allocated Containers
            var srcType = needSourceType.ToString();
            AllocationNeed allocNeed = repository.SearchFor(
                x => x.FacilityId == intFacilityId
                && x.NeedSourceType == srcType
                && x.NeedSourceId == intNeedSourceId
            ).First();

            //return repository.Delete(allocNeed, true);
            ctx.Entry(allocNeed).State = System.Data.EntityState.Deleted;
            ctx.SaveChanges();

            //Deallocation was successful
            return ActionConfirmation<int>.CreateSuccessConfirmation(
                string.Format(
                    "Successfully deleted Need Id: {0} {1}",
                    needSourceType.ToString(),
                    intNeedSourceId
                ),
                intNeedSourceId
            );
        }
4

1 に答える 1

2

コンテキストの 1 つのバージョンを渡さなければならないという私の仮定は正しくありませんでした。複数のコンテキストでトランザクションをラップする方法を説明している良い記事を見つけました。

于 2013-03-04T15:52:21.647 に答える