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用存储过程批量添加修改数据的更多相关文章
- ASP.NET MVC 5 - 给数据模型添加校验器
在本节中将会给Movie模型添加验证逻辑.并且确保这些验证规则在用户创建或编辑电影时被执行. 拒绝重复 DRY ASP.NET MVC 的核心设计信条之一是DRY: "不要重复自己(DRY ...
- ASP.NET MVC 5 学习教程:修改视图和布局页
原文 ASP.NET MVC 5 学习教程:修改视图和布局页 起飞网 ASP.NET MVC 5 学习教程目录: 添加控制器 添加视图 修改视图和布局页 控制器传递数据给视图 添加模型 创建连接字符串 ...
- [转]ASP.NET MVC 5 - 给数据模型添加校验器
在本节中将会给Movie模型添加验证逻辑.并且确保这些验证规则在用户创建或编辑电影时被执行. 拒绝重复 DRY ASP.NET MVC 的核心设计信条之一是DRY: "不要重复自己(DRY ...
- [转]ASP.NET MVC 入门8、ModelState与数据验证
ViewData有一个ModelState的属性,这是一个类型为ModelStateDictionary的ModelState类型的字典集合.在进行数据验证的时候这个属性是比较有用的.在使用Html. ...
- ASP.NET MVC 入门8、ModelState与数据验证
原帖地址:http://www.cnblogs.com/QLeelulu/archive/2008/10/08/1305962.html ViewData有一个ModelState的属性,这是一个类型 ...
- ASP.NET MVC系列:为视图添加查询功能
首先,在MoviesController里添加一个查询方法,代码如下 public ActionResult SearchIndex(string title) { //查询数据库中的电影表 var ...
- EF 批量 添加 修改 删除
1批量添加 db.T_Investigator.AddRange(list) 2批量删除 db.T_Investigator.RemoveRange(list) 3批量修改 for 循 ...
- ASP.NET MVC 右键点击添加没有区域(Area)、控制器、试图等选项
在MVC项目中准备添加控制器.区域时发现没有控制器这个选项,当时没有在意以为VS出问题了,网上所搜了一下,有人说没有安装:Microsoft.AspNet.Mvc或者需要升级. 本次的解决如下: 1) ...
- spring MVC 后端 接收 前端 批量添加的数据(简单示例)
第一种方式:(使用ajax的方式) 前端代码: <%@ page contentType="text/html;charset=UTF-8" language="j ...
随机推荐
- net stop 出现1060错误
net stop时出现1060错误,答案: 原来,net stop后面不能想当然地加上服务,而要在‘服务’里看看,那个服务究竟叫什么名字. 比如,我的mysql安装时不叫mysql,而是mysql5 ...
- iOS开发——汉字转拼音
以前有一次做一个天气预报的项目,有一个功能是输入城市名,请求该城市的天气,需要把汉字转化成拼音,比如深圳——>shenzhen,加入到参数中.当时在网上找了一下,网友给出的方法很多都用不了,现在 ...
- Thinking in scala (2)---- 最大公约数
gcd.scala object gcd{ def main(args:Array[String]){ println( gcd1(args(0).toInt,args(1).toInt)) prin ...
- 怎样编制excel序列目录
怎样编制序列目录 原帖内容:http://www.excelpx.com/forum.php?mod=viewthread&tid=164190&extra=%26page%3D1&a ...
- C++ 虚基类表指针字节对齐
下面博客转载自别人的,我也是被这个问题坑了快两天了,关于各种虚基类,虚继承,虚函数以及数据成员等引发的一系列内存对齐的问题再次详细描述 先看下面这片代码.在这里我使用了一个空类K,不要被这个东西所迷惑 ...
- Javascript 查找元素
DOM定义了多种查找元素的方法,除了我们常用的getElementById(),还有getElementsByTagName()和getElementsByName().使用这几种方法方法我们可以查找 ...
- Python3基础 内嵌函数 简单示例
镇场诗: 诚听如来语,顿舍世间名与利.愿做地藏徒,广演是经阎浮提. 愿尽吾所学,成就一良心博客.愿诸后来人,重现智慧清净体.-------------------------------------- ...
- JS 禁止刷新和右键
<!doctype html> <html> <head> <meta charset="utf-8"> <title> ...
- PHP做负载均衡回话保持问题参考
最近一个项目的服务器老是出现Session数据丢失问题,导致用户莫名其妙的退出,原因是太相信我们的运维人员所谓的负载均衡会话保持的概念.会话保持 的原理就是负载均衡通过Cookie来分发那个客户连接被 ...
- Failed to register Grid Infrastructure type ora.mdns.type
安装11g的集群软件的时候,在最后运行root.sh脚本时候,没有执行成功,最后提示如下错误: [root@r2 ~]# /u01/app/11.2.0/grid_1/root.sh Performi ...