私はASP.Net MVCアプリケーションを開発しており、データベースのデータを部分的なポストバックを介して更新しようとしているときにbizzareの問題に遭遇しています。私はHTTP、AJAXなどについてはまだまだ新しいので、明白な誤りだと思っています。ASP.NET MVC部分的なビューポストバック、一貫性のない更新とBizzareの動作
基本的に、コンテンツエリアと評価をリンクするテーブルを更新しようとすると、アップデートが動作することがあり、時にはそうではありません。 bizzareとは、私が投稿した後、MVCアプリケーションからデータベースに直接照会して、実際に期待される変更が行われたことを確認するだけです(これはViewBag.DebugInfoのすべてが以下のコードで行っています)。どんな場合でも、クエリは私が見たいものを返します。しかし、テーブルでSSMSを照会すると、時々変更が反映されることがあります。
私のMVCアプリケーションのテーブルへの直接クエリが、SSMS経由ではないことが明確にわかるうちに、更新が完了したことをどのように示していますか?静かなロールバックや何かがありますか?これは狂っていて、どんな助けでも大歓迎です。情報の
数ビット:私はMVCの外以下assessmentContentクラスから「saveTheData」機能を実行すると、それは常に成功する
- 。
- 更新は最初の投稿では常に成功しています。
- 更新は、後続の投稿の約半分に過ぎません。
- 更新が成功しなかった場合でも、MVCアプリケーションからのダイレクトクエリのチェックでは、更新によってテーブルに移動したことが示されているようです。
- 私は間違いなくパターンを作り出すことができます。つまり、より高いcontentId値に更新しようとするたびに成功します。より低いcontentIdに更新しようとすると、成功しません。たとえば、値1(Math)から2(Reading)への更新は常に行われますが、その逆は実行されません。このパターンは、親ビューからの最初の投稿であるか、Linqpad経由で更新されたものであるかを明示しません。
- ログテーブルに書き込むデータベーステーブルにinsert、update、およびdeleteトリガーを挿入して、変更がロールバックされているかどうかを確認します。しかし、失敗したログテーブルのエントリはありません。しかし、ロールバックがトリガーも元に戻すかどうかはわかりません。
- Operation = 'LOP_ABORT_XACT'のためにフィルタリングされたdbo.fn_dblog()を照会しましたが、何も表示されませんでした。私は私のMVCアプリケーションの外にそれを使用する場合
public class assessmentContent { public int? assessmentId { get; set; } public List<short> baseline { get; set; } = new List<short>(); public List<short> comparison { get; set; } = new List<short>(); public assessmentContent() { if (assessmentId != null) refreshTheData(); } public assessmentContent(int assessmentId) { this.assessmentId = assessmentId; refreshTheData(); } public void saveTheData() { List<short> upserts = comparison.Except(baseline).ToList(); List<short> deletes = baseline.Except(comparison).ToList(); foreach (var upsert in upserts) reval.ach.addAssessmentContent(assessmentId, upsert); foreach (var delete in deletes) reval.ach.deleteAssessmentContent(assessmentId, delete); refreshTheData(); } void refreshTheData() { baseline = reval.ach.assessmentContent(assessmentId).ToList(); comparison = reval.ach.assessmentContent(assessmentId).ToList(); } }
ロジックが正常に動作します:
はここで取得し、データを更新私のクラスです。例えば、linqpad経由で使用する場合、問題はありません。 assessmentContent()に「getAssessmentContent()」という名前を付けることができます。私は3層アーキテクチャやモデル - ビュー - コントローラの構造は最高の実装がない可能性があることを承知している
public class ContentsModel {
public int? assessmentId { get; set; }
public List<short> comparison { get; set; }
}
public class ContentsController : Controller {
public static string nl = System.Environment.NewLine;
public ActionResult ContentsView(int assessmentId) {
ViewBag.DebugInfo = new List<string>();
var vm = new ContentsModel();
vm.assessmentId = assessmentId;
vm.comparison = reval.ach.assessmentContent(assessmentId).ToList();
return View("~/Views/ach/Contents/ContentsView.cshtml", vm);
}
public ActionResult update(ContentsModel vm) {
ViewBag.DebugInfo = new List<string>();
sqlFetch();
ViewBag.DebugInfo.Add($"VM Pased In {vm.assessmentId} c{vm.comparison.intsJoin()}");
sqlFetch();
var crud = new crud.ach.assessmentContent((int)vm.assessmentId);
ViewBag.DebugInfo.Add($"newly fetched CRUD {crud.assessmentId} b{crud.baseline.intsJoin()} c{crud.comparison.intsJoin()}");
sqlFetch();
crud.comparison = vm.comparison;
ViewBag.DebugInfo.Add($"CRUD after crud_comparison = vm_comparison {crud.assessmentId} b{crud.baseline.intsJoin()} c{crud.comparison.intsJoin()}");
sqlFetch();
crud.saveTheData();
ViewBag.DebugInfo.Add($"CRUD after save {crud.assessmentId} b{crud.baseline.intsJoin()} c{crud.comparison.intsJoin()}");
sqlFetch();
vm.comparison = crud.comparison;
ViewBag.DebugInfo.Add($"VM after vm_comparison = crud_comparison {vm.assessmentId} c{vm.comparison.intsJoin()}");
sqlFetch();
return PartialView("~/Views/ach/Contents/ContentsView.cshtml", vm);
}
void sqlFetch() {
ViewBag.DebugInfo.Add(
"SQL Fetch " +
Sql.ExecuteOneColumn<short>("select contentId from ach.assessmentContent where assessmentId = 12", connections.research).intsJoin()
);
}
}
public static partial class extensions {
public static string intsJoin(this IEnumerable<short> ints) {
var strings = new List<string>();
foreach (int i in ints)
strings.Add(i.ToString());
return string.Join(",", strings);
}
}
:
は、ここに私の部分図のためのコントローラ、およびいくつかの関連するコードですここに。
モデルの変更点ごとにデータベーステーブルに直接チェックしました。
部分図:
@model reval.Views.ach.Contents.ContentsModel
@using reval
@{Layout = "";}
<div id="contentDiv">
<form id="contentForm">
@Html.HiddenFor(m => m.assessmentId)
@Html.ListBoxFor(
m => m.comparison,
new reval.ach.content()
.GetEnumInfo()
.toMultiSelectList(
v => v.Value,
d => d.DisplayName ?? d.Description ?? d.Name,
s => Model.comparison.Contains((short)s.Value)
),
new { id = "contentListBox" }
)
</form>
<br/>
@foreach(string di in ViewBag.DebugInfo) {
@Html.Label(di)
<br/>
}
</div>
<script>
$("#contentListBox").change(function() {
$.ajax({
url: "/Contents/update",
type: "get",
data: $("#contentForm").serialize(),
success: function (result) {
$("#contentDiv").html(result);
},
error: function (request, status, error) {
var wnd = window.open("about:blank", "", "_blank");
wnd.document.write(request.responseText);
}
});
})
</script>
そして最後に、メインビューからの呼び出し:
<div id="testDiv">
@if (Model.assessment != null && Model.assessment.assessmentId != null) {
Html.RenderAction("ContentsView", "Contents", new { assessmentId = Model.assessment.assessmentId });
}
</div>
私は間違いなく確信していますが、同時に私はトランザクションの問題が疑いのある唯一の理由は、症状のためだと言うでしょう。私はトランザクションに関係する明示的なコードを書いていません。私の答えで言及された私の試みを除いて、あなたが私がどのようにトラブルシューティングするかに関するアドバイスがあれば教えてください。ありがとう。 – pwilcox
さて、あなたは私を正しい道のりに置いたと思う。私が安心して言うのは早いですが、明示的なトランザクションを追加し、基礎となるデータアクセスコードにコミットすることで問題を解決できたかもしれません。そうでない場合でも、似たような問題を抱えている興味のあるユーザーにとっては、問題の可能性を検討することが重要です。実際に私が解決策を持っているなら、私は返信します。ありがとうございました!!!。 – pwilcox
私はそれが問題ではないようであることを報告することを後悔します。さらに、上記の障害の順序パターンは保持されていないようです。 – pwilcox