-1

以下のコードは、データベースに行を追加するか、既存の行を更新するために使用されます。

IEnumerable<Guid> fieldIds = glen.ComplianceField.Select(field => field.id);
ComplianceData data;
foreach (Guid fieldId in fieldIds)
{
    if (!checkEntity(fieldId, Extra.grn))
    {
        if (collection[fieldId.ToString()] != null)
        {
            if (glen.ComplianceData.Where(compData => (compData.fieldId == fieldId) && (compData.grn == Extra.grn)).Count() == 0)
            {
                data = new ComplianceData();
                glen.ComplianceData.Add(data);
            }
            else
                data = glen.ComplianceData.First(compData => (compData.fieldId == fieldId) && (compData.grn == Extra.grn));
            data.fieldId = fieldId;
            data.grn = Extra.grn;
            data.value = collection[fieldId.ToString()];
        }
    }
}
glen.SaveChanges();

ただし、場合によっては (ユーザーが送信ボタンを複数回クリックしたと思われます)、データベース内で行が複製されます (サーバーが特に遅い場合は複数回)。この問題は、エントリを最初に作成したときにのみ発生し、その後、最初のエントリが期待どおりに更新されます。

コンテキストの ChangeTracker プロパティを使用しようとしましたが、glen コンテキストは連続する各リクエストで異なるオブジェクトであるため、うまくいきません。アクションの実行中にデータベース テーブルをロックする方法、または同じ要求が行われたばかりの場合にアクションがデータベースの更新を実行しないようにする方法はありますか?

4

2 に答える 2

0

私はついにこれを行うことがSystem.Transactionsできました(アクセスするには新しい参照を追加する必要がありました)。私の最後のスニペットは -

IEnumerable<Guid> fieldIds = glen.ComplianceField.Select(field => field.id);
ComplianceData data;
    using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = System.Transactions.IsolationLevel.Serializable}))
        {
            foreach (Guid fieldId in fieldIds)
            {
                if (collection[fieldId.ToString()] != null)
                {
                    if (glen.ComplianceData.Where(compData => (compData.fieldId == fieldId) && (compData.grn == Extra.grn)).Count() == 0)
                    {
                        data = new ComplianceData();
                        glen.ComplianceData.Add(data);
                    }
                    else
                        data = glen.ComplianceData.First(compData => (compData.fieldId == fieldId) && (compData.grn == Extra.grn));
                        data.fieldId = fieldId;
                        data.grn = Extra.grn;
                        data.value = collection[fieldId.ToString()];
                }
            }
            glen.SaveChanges();
            scope.Complete();
        }

この回答に一部感謝https://stackoverflow.com/a/13097278/1173776

于 2013-09-16T13:59:28.960 に答える
0

ボタンの複数回の送信クリックが原因であると思われる場合は、アクティブ化されたらすぐにボタンを無効にするなど、さまざまな手順を実行してこれを停止できます。また、複数のリクエストが通過していないことを確認するために、サーバー側のチェックも行う必要があります。

于 2013-09-10T13:05:25.600 に答える