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数据时还要把带删除标志的行筛选掉,又要添加好多代码
不知道你们是否有很好的解决方案