ASP.NET MVC用存储过程批量添加修改数据操作
用entity framework 进行数据库交互,在代码里直接用lamda表达式和linq对数据库操作,中间为程序员省去了数据库访问的代码时间,程序员直接可以专注业务逻辑层的编写。但是对于比较复杂的表关系关联查询或者修改就比较费劲了。通常可以采用的方式是用ef执行sql语句或者“存储过程”,特别是执行复杂批量任务,当然也可以在mvc底层用ado.net,这里就不多说了。怎么做批量呢?这里讲讲在ef下用存储过程批量添加修改数据。
需求是这样的:需要批量添加修改产品类别的投放任务数额,每月更新一次,月初归0,添加后会显示在表单中,也就是添加修改都在一个页面。
思路:前端先用表单把类别动态读取出来,用viewbag动态加载到页面,如果已经有添加当月任务数,就读取出来显示到表单上,可以进行修改,否则就是全新添加当月任务数。提交表单的时候出现了个问题,怎么把类别编号post到后台,我想了一个办法,那就是加一个隐藏域,值为"type|类别编号",后台取数据是判断是否包含type来判断是否是类别编号,然后用split('|')[1]循环读取。
怎么传递到数据库呢?我把数据存到datatable里面,然后用ef执行存储过程,把datatable当着参数传到数据库处理。
数据库怎么处理这个datatable呢?用自定义数据类型处理
代码步骤:
代码方面
控制器 显示动态表单
public actionresult markettaskadd() { var marketype = new marketdataprovider().getbtiddata().where(a=>a.id!="0");//读取类别 var rel = new markettaskprogressprovider().getmarketmonthtask(); if (rel.count() > 0) { viewbag.datas = rel.join(marketype, a => a.mkbtid, b => int.parse(b.id), (a, b) => new { a.mkbtid, b.id,b.text,a.tasknum }).select(s=>new viewsmodel { id= s.mkbtid.tostring() ,text=s.text,tasknum=s.tasknum.tostring()}); }//如果有数据关联数据 else { var rel2 = marketype.select(s => new viewsmodel{ id = s.id, text = s.text, tasknum="" }).tolist();//直接返回表单 viewbag.datas = rel2; } return view(); }
开始想直接返回object,结果前台遍历不支持,故新建实体类viewsmodel。
view页面
@foreach (var modelmarkets in viewbag.datas) { <div class="row" style="margin-top:10px"> <div class="col-md-4 text-right"><span class="red">*</span> @modelmarkets.text </div> <div class="col-md-8 text-left"> <input name="text|@modelmarkets.id" class="form-control" style="width:50%" value="@modelmarkets.tasknum" type="text" /> <input type="hidden" name="type|@modelmarkets.id" value="type|@modelmarkets.id" /><!--隐藏表单--> </div> </div> }
控制器 post提交表单
[httppost] public actionresult markettaskadd(string type) { var strform = request.form; int userid = adminuser!=null?adminuser.userid:0;//创建人或者修改人id datatable dt = new datatable(); dt.columns.add("mkbtid",type.gettype("system.int32")); dt.columns.add("tasknum", type.gettype("system.int32")); list<string> temp1 = new list<string>(); list<string> temp2 = new list<string>(); for (int i = 0; i < strform.count; i++) { if (strform[i].contains("type")) { temp1.add(strform[i].split('|')[1]); } else { temp2.add(strform[i]); }//循环分解表单 } for (int i = 0; i < temp1.count; i++) { datarow dr = dt.newrow(); dr[0] = temp1[i]; dr[1] = temp2[i]; dt.rows.add(dr);//批量添加到datatable } var rel = new markettaskprogressprovider().markettaskaddoredit(userid,dt);//调用方法 if(rel) viewbag.js = "<script>alert('操作成功!');window.location.href='/markettaskprogress/markettaskadd';</script>"; else viewbag.js = "<script>alert('操作失败!');window.location.href='/markettaskprogress/markettaskadd';</script>"; list<viewsmodel> listtemp = new list<viewsmodel>(); listtemp.add(new viewsmodel { id = "", text = "", tasknum = "" }); viewbag.datas = listtemp; return view(); } }
提交到数据库方法:
public bool markettaskaddoredit(int userid,datatable dt) { using (dssentity entity = new dssentity())//不推荐用using { sqlparameter p = new sqlparameter("@createduser",dbtype.int32); p.value = userid; sqlparameter p1 = new sqlparameter("@tablemarkettask",dbtype.object); p1.value = dt; p1.typename = "tablemarkettask";//参数处理,貌似自定义函数必须加这个函数名称 var rel = entity.database.executesqlcommand("exec[dbo].[pr_markettaskaddoredit] @createduser,@tablemarkettask", p,p1);//ef执行存储过程 return rel > 0; } }
数据库方面
首先根据情况建自定义类型,如下
-- create the data type create type [dbo].[tablemarkettask] as table( [mkbtid] [varchar](50) not null,--投放类别 [tasknum] [varchar](50) not null--投放任务数量 )
也可以用sql server 工具手动新建
第二是建存储过程
create procedure pr_markettaskaddoredit @createduser int, @tablemarkettask tablemarkettask readonly --自定义类型的参数,必须加readonly。 as declare @tempcreateduser int if exists(select top 1 * from marketmonthtask t where months=month(getdate()))--当月存在的话就修改 begin select top 1 @tempcreateduser=createduser from marketmonthtask t where months=month(getdate()) delete from marketmonthtask where months=month(getdate()) insert into marketmonthtask(mkbtid,tasknum,months,updateuser,createduser) select mkbtid,tasknum,month(getdate()),@createduser,@tempcreateduser from @tablemarkettask end else--或者直接插入 begin insert into marketmonthtask(mkbtid,tasknum,months,createduser) select mkbtid,tasknum,month(getdate()),@createduser from @tablemarkettask end
自定义类型可以像表那样自己查询,很方便。自定义函数不容易调试。ef直接调用存储过程也不支持自定义函数。
以上所述是小编给大家介绍的asp.net mvc用存储过程批量添加修改数据操作,希望对大家有所帮助