用Entity Framework 进行数据库交互,在代码里直接用lamda表达式和linq对数据库操作,中间为程序员省去了数据库访问的代码时间,程序员直接可以专注业务逻辑层的编写。但是对于比较复杂的表关系关联查询或者修改就比较费劲了。通常可以采用的方式是用EF执行SQL语句或者“存储过程”,特别是执行复杂批量任务,当然也可以在MVC底层用ADO.NET,这里就不多说了。怎么做批量呢?这里讲讲在EF下用存储过程批量添加修改数据。
需求是这样的:需要批量添加修改产品类别的投放任务数额,每月更新一次,月初归0,添加后会显示在表单中,也就是添加修改都在一个页面。
思路:前端先用表单把类别动态读取出来,用viewbag动态加载到页面,如果已经有添加当月任务数,就读取出来显示到表单上,可以进行修改,否则就是全新添加当月任务数。提交表单的时候出现了个问题,怎么把类别编号post到后台,我想了一个办法,那就是加一个隐藏域,值为"Type|类别编号",后台取数据是判断是否包含Type来判断是否是类别编号,然后用split('|')[1]循环读取。
怎么传递到数据库呢?我把数据存到datatable里面,然后用EF执行存储过程,把datatable当着参数传到数据库处理。
数据库怎么处理这个datatable呢?用自定义数据类型处理
代码步骤:
代码方面
控制器 显示动态表单
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
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页面
1
2
3
4
5
6
7
8
9
10
|
@ 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提交表单
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
[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();
}
}
|
提交到数据库方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
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;
}
}
|
数据库方面
首先根据情况建自定义类型,如下
1
2
3
4
5
|
-- Create the data type
CREATE TYPE [dbo].[tableMarketTask] AS TABLE(
[MKBTID] [varchar](50) NOT NULL,--投放类别
[TaskNum] [varchar](50) NOT NULL--投放任务数量
)
|
也可以用sql server 工具手动新建
第二是建存储过程
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
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用存储过程批量添加修改数据操作,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对服务器之家网站的支持!
原文链接:http://www.cnblogs.com/xbhp/archive/2017/02/16/6403961.html