Asp.Net MVC +EntityFramework主從表新增編輯操作的實現
對於MVC中同時對主從表的表單操作在網上現有的解決很少,而這樣的操作在做業務系統中是經常為遇到的。我在網上搜索了很久都沒有發現很完整的實例或非常好的解決方案,所以我很想和大家討論一下又什么更好的解決方案。
一旦有更好的方式我會把它集成到模板中實現自動生成。所以很希望得到大家的幫助。在這里我先拋磚引玉了。
Demo代碼在 https://github.com/neozhu/MVC5-Scaffolder 下載
先看一下我的Demo實例

實體類的結構
實現的操作界面如下圖



功能:
查詢頁面上可以單擊新增和編輯進行對數據維護
頁面的結構是上部是維護表頭,下部的Table是現實子表數據,對子表數據的維護使用bootstrap popup modal的方式操作。
具體實現
View層的代碼

Index :查詢Table List
Create :新增頁面
Edit : 編輯頁面
EditForm :Partial View內嵌在Create 和Edit頁面中
_OrderDetailForm : pupup 子表維護表單頁面
Create,和Edit頁面通過Ajax Post 把數據提交到后台的Controller進行操作
代碼如下
<script type="text/javascript">
var $orderdetailstable = {};
var ObjectState = "Added";
$(document).ready(function () {
$('#orders').submit(function () {
var actionurl = $(this).attr('action');
var orderdetails = $orderdetailstable.bootstrapTable('getData');
console.log(orderdetails);
var newitem = {
Id:0,
Customer: $('#Customer','#orders').val(),
ShippingAddress: $('#ShippingAddress', '#orders').val(),
OrderDate: $('#OrderDate', '#orders').val(),
ObjectState:ObjectState,
OrderDetails: orderdetails
};
console.log(newitem);
$.ajax({
url: actionurl,
type: "POST",
dataType: "json",
contentType: "application/json; charset=utf-8",
data: JSON.stringify(newitem),
success: function (result) {
self.location = "/Orders/Index";
//alert("success " + result.UserName);
},
error: function (result) {
alert("Failed");
}
});
return false;
});
});
</script>
通過Jquery 獲取表頭和表體數據 序列化成Json對象然后Post到后台
這里有個問題關於Josn 序列化的 所有的實體 Order都集成Entity這個基類,Entity有個枚舉類型的字段 [ObjectState] 用了好多方法都沒有辦法把這個字段提交到后台,在Controller的Create,Edit 方法中的Order就是沒有[ObjectState]這個字段的值;所以在Controller層還得寫很多代碼來修改實體狀態
Controller層代碼
這里就只貼Create方法的代碼
// GET: Orders/Create
public ActionResult Create()
{
//Detail Models RelatedProperties
var orderRepository = _unitOfWork.Repository<Order>();
ViewBag.OrderId = new SelectList(orderRepository.Queryable(), "Id", "Customer");
var productRepository = _unitOfWork.Repository<Product>();
ViewBag.ProductId = new SelectList(productRepository.Queryable(), "Id", "Name");
return View();
}
// POST: Orders/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
//[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "OrderDetails,Id,Customer,ShippingAddress,OrderDate")] Order order)
{
if (ModelState.IsValid)
{
order.ObjectState = ObjectState.Added;
foreach (var detail in order.OrderDetails)
{
detail.ObjectState = ObjectState.Added;
if (detail.Product != null)
detail.Product.ObjectState = ObjectState.Detached;
}
_orderService.InsertOrUpdateGraph(order);
_unitOfWork.SaveChanges();
DisplaySuccessMessage("Has append a Order record");
//return RedirectToAction("Index");
return Json("{Status:Success}", JsonRequestBehavior.AllowGet);
}
DisplayErrorMessage();
return View(order);
}
因為沒辦法在前端把[ObjectState]這個字段的值序列化所以寫了一個foreach來修改狀態,不知道你們有沒有什么好的解決方案
Popup Modal編輯子表數據代碼
新增表體按鈕
$('#neworderdetailbutton').on('click', function (e) {
if ($("form").valid()) {
var url="/Orders/CreateOrderDetail"
$.get(url , function (data) {
//console.log(data);
var index=-1;
$('#orderdetailformModal-body').html(data);
$('#rowindex').val(index);
$('#Id').val(0);
$('#orderdetailformModal').modal('toggle');
});
}
e.preventDefault();
//Return false regardless of validation to stop form submitting
//prior to ajax doing its thing
return false;
})
OrderController 添加一個新增表體和修改表體的Action用於生產對應的Partial View
我在這里也試過在OrderController中不添加對子表操作的Action,完全使用JS完成對行的操作,但在對編輯現有表體數據時出現了問題。后來注銷掉了@*@Html.Partial("_OrderDetailForm")*@
現在還有非常棘手的問題就是如何進行刪除操作,一旦在編輯狀態下,把其中一個表體的記錄刪掉,刪除后就沒辦法把數據提交到后台,而不刪添加一個刪除標志,這同樣也會帶來很多操作,如Table 在laod數據時還要把帶刪除標志的行篩選掉,又要添加好多代碼
不知道你們是否有很好的解決方案
