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數據時還要把帶刪除標志的行篩選掉,又要添加好多代碼
不知道你們是否有很好的解決方案