MVC学习笔记四:利用Entity Framework调用存储过程
2017-12-07 20:39
405 查看
MVC利用EF调用存储过程
这一章记录一下,如何通过EF调用数据库中的存储过程。依然按照前面的两种数据库操作方式,一种是DbContext,第二种是ObjectContext.
在这之前,先在数据库中建立几张简单的表,方便做实例用。相关脚本如下,可供参考:
第一张表:City
[sql]
view plain
copy
USE [mydb]
GO
/****** Object: Table [dbo].[City] Script Date: 11/08/2013 23:06:16 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[City](
[CityId] [int] IDENTITY(1,1) NOT NULL,
[ChinaName] [nchar](10) NOT NULL,
[PinYin] [nvarchar](50) NOT NULL,
[Description] [nvarchar](50) NULL,
CONSTRAINT [PK_City] PRIMARY KEY CLUSTERED
(
[CityId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
然后手工插入几条数据,这里只简单插入3条数据如下:
再建立一张商店表:Store
[sql]
view plain
copy
USE [mydb]
GO
/****** Object: Table [dbo].[Store] Script Date: 11/08/2013 23:11:43 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Store](
[StoreId] [int] IDENTITY(1,1) NOT NULL,
[StoreName] [nvarchar](50) NOT NULL,
[CityId] [int] NOT NULL,
[Description] [nvarchar](50) NULL,
CONSTRAINT [PK_Store] PRIMARY KEY CLUSTERED
(
[StoreId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
手工插入几条数据如下,这里有7条:
最后建立一张销售表:Sale
[sql]
view plain
copy
USE [mydb]
GO
/****** Object: Table [dbo].[Sale] Script Date: 11/08/2013 23:14:42 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Sale](
[Id] [int] IDENTITY(1,1) NOT NULL,
[BusinessDate] [datetime] NOT NULL,
[StoreId] [int] NOT NULL,
[TotalAccount] [decimal](18, 0) NOT NULL,
CONSTRAINT [PK_Sale] PRIMARY KEY CLUSTERED
(
[BusinessDate] ASC,
[StoreId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
手工插入几条数据,如下:
好了,这里示例实现的简单功能就是:取出2013年11月1号所有店铺各自的销售金额一览。
这里需要写一个简单的存储过程,返回类似下面格式的表:
在数据库中新建一个存储过程:GetIphoneSaleDailyReport,它接受一个日期形式的参数。这里为了测试方便,指定成'2013-11-1'这一天。
[sql]
view plain
copy
use mydb
go
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: <Author,,Name>
-- Create date: <Create Date,,>
-- Description: <Description,,>
-- =============================================
CREATE PROCEDURE GetIphoneSaleDailyReport
-- Add the parameters for the stored procedure here
@businessDate as datetime
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
select CONVERT(varchar(100),a.BusinessDate,23) as 日期,aa.ChinaName as '城市',aa.StoreName as '分店',aa.Description as '分店说明',a.TotalAccount '销售总计'
from mydb.dbo.Sale as a
left join (select c.ChinaName,b.StoreName,b.StoreId,b.Description from mydb..Store b inner join mydb..City c on b.CityId=c.CityId) aa
on a.StoreId=aa.StoreId
where a.BusinessDate=@businessDate
END
GO
可以先在数据库测试一下,看看存储过程是否新建成功:
[sql]
view plain
copy
exec GetIphoneSaleDailyReport '2013-11-1'
如果返回上面的一览表,就说明存储过程没什么问题了。
然后打开之前介绍的示例项目FirstMvcWithEF,双击打开Apples.edmx文件,鼠标右击空白处选择“从数据库更新模型”如下:
将存储过程添加到edmx文件中:
点击完成,结束添加。这时候从edmx的模型浏览器里可以看出,多出了一个存储过程,如下:
同样,再在edmx界面空白处,右击鼠标 新增 函数导入:
设置界面如下,选择之前加入的存储过程,由于存储过程返回的是一张表,这里选择复杂类型,而且系统也自动帮我创建了一个复杂类型,点击“获取列信息”可以看到存储过程返回的各种列名及其它列类型信息。
上面的准备工作已经做完,接下来介绍两种方式执行存储过程。
一.DbContext方式
如果使用的是VS2012,那么系统默认指定的可能就是这种方式。首先,在Controllers文件夹里新建一个控制器,取名“ReportController”,在它的默认Index方法上新建一个视图。
编译项目,在Index方法上新建一个强类型的视图,但是我始终找不到上面的复杂类型“GetIphoneSaleDailyReport_Result”,在项目其它地方也引用不到它,感到很奇怪,所以这种方式就先不能实现了,如有朋友知道如何处理,可以帮忙指点下
但是具体的调用存储过程是可以使用如下的方式:
[csharp]
view plain
copy
public virtual IEnumerable<TEntity> GetWithRawSql(string query, params object[] parameters)
{
return dbSet.SqlQuery(query, parameters).ToList();
}
public ActionResult Details(int id)
{
var query = "exec T_Get @p0";
return View(unitOfWork.CourseRepository.GetWithRawSql(query, id).Single());
}
二.ObjectContext方式
按照之前介绍的方式,将方式改成ObjectContext,不清楚的可以看这里,有可能还要删除Iphones.cs文件(如果之前使用DbContext遗留下来的话)。这时候再去新建上面的Index视图时,选择强类型,就可以找到复杂属性“GetIphoneSaleDailyReport_Result”了
,注意模板支架选择List:
然后修改Index方法如下:
[csharp]
view plain
copy
public ActionResult Index()
{
mydbEntities db = new mydbEntities();
var results = db.GetIphoneSaleDailyReport(DateTime.Parse("2013-11-1"));
return View(results);
}
修改对应的Index视图如下:
[csharp]
view plain
copy
@model IEnumerable<FirstMvcWithEF.Entities.GetIphoneSaleDailyReport_Result>
@{
ViewBag.Title = "Index";
}
<h2>测试存储过程</h2>
<div id="grid">
@{
var grid = new WebGrid(source: Model.ToList(),
defaultSort: "分店",
rowsPerPage: 7);
}
@grid.GetHtml(
tableStyle: "table",
headerStyle: "gridhead",
alternatingRowStyle: "rowStyle",
columns: grid.Columns(
grid.Column("日期","日期",null,null,false),
grid.Column("城市","城市"),
grid.Column("分店","分店"),
grid.Column("分店说明","分店说明"),
grid.Column(null,"销售总计",format:@<text><input class="test-box" id="test-box" name="test-box" type="text" value="@item.销售总计"/></text>)
)
)
</div>
OK,编译运行,看下效果,注意视图在Report下,地址后面要加/Report:
到此,调用存储过程成功了。
相关文章推荐
- MVC学习笔记四:利用Entity Framework调用存储过程
- MVC3学习第十一章 葵花点穴手之隔空点穴----MVC3下利用EF和LINQ进行简单的多表联查、排序以及在Razor视图中调用自定义类
- MyBatis学习笔记(六)——调用存储过程
- 【CI学习笔记】利用jquery中的ajax,调用接口,实现登录
- Android 学习笔记——利用JNI技术在Android中调用、调试C++代码
- 【Spring学习笔记-MVC-5】利用spring MVC框架,实现ajax异步请求以及json数据的返回
- C++学习笔记(13)——利用对象、引用、指针调用虚函数
- ASP.NET 3.5核心编程学习笔记(58):利用页面方法来进行远程调用
- 强大的DataGrid组件[6]_调用存储过程服务端分页——Silverlight学习笔记[14]
- Android 学习笔记——利用JNI技术在Android中调用、调试C++代码
- Android 学习笔记——利用JNI技术在Android中调用、调试C++代码
- Android 学习笔记——利用JNI技术在Android中调用、调试C++代码
- Android 学习笔记——利用JNI技术在Android中调用、调试C++代码
- C++学习笔记(13)——利用对象、引用、指针调用虚函数
- 【转】Android 学习笔记——利用JNI技术在Android中调用、调试C++代码
- Mybatis学习笔记-mybatis调用存储过程
- Android 学习笔记——利用JNI技术在Android中调用、调试C++代码
- Android 学习笔记——利用JNI技术在Android中调用、调试C++代码
- C++学习笔记---利用对象、引用、指针调用虚函数
- MVC描述对象的类关系图/调用关系图【学习笔记】