我的MVC之旅(4)-------Models and Data Access[翻译]
致歉
说好了这回坚持的,但是还是没能坚持下来,之前忙公司的一个项目导致一个多月没更新了,好不容易QA第一轮通过,就赶紧继续努力学习吧.
回顾
之前说了视图以及模型视图,模型视图即与模型强类型绑定的视图, 与模型绑定的视图专门处理模型的CURD操作.这次继续学习模型和数据访问,这里用到的数据访问技术是EF,而且是代码方式的EF.也一起学习吧.
使用EF访问数据库(Code-first)
我们将使用包含在 ASP.NET MVC 3 项目中的实体框架 (EF) 来查询和更新数据库。EF 是一个灵活的对象关系映射 (ORM) 数据 API,使开发人员能够以面向对象的方式查询和更新数据.
EF 4.0支持Code-first 开发模式,Code-first 允许通过简单的类来创建模型对象,甚至可以通过简单类生成数据库或者表.
一个小插曲(如何使用EF初始化不存在的数据库并插入数据)
在继续之前,先来做一点知识储备;
- 添加模型Artist到模型文件夹,内容如下:
public class Artist{
public int ArtistId { get; set; }
public string Name { get; set; }
}- 更新Album模型:
public class Album{
public int AlbumId
{
get;
set;
}
public int GenreId { get; set; }
public int ArtistId { get; set; }
public string Title { get; set; }
public decimal Price { get; set; }
public string AlbumArtUrl { get; set; }
public Genre Genre { get; set; }
public Artist Artist { get; set; }
}- 更新音乐体裁模型:
public class Genre
{
public int GenreId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public List<Album> Albums { get; set; }
}- 数据库:添加App_Data 到项目中,在web.config中的connectionStrings节点下添加如下内容:
<add name="MusicStoreEntities"
connectionString="Data Source=|DataDirectory|MvcMusicStore.sdf"
providerName="System.Data.SqlServerCe.4.0"/>- 在模型文件夹中添加类:MusicStoreEntities继承自DbConetxt(System.Data.Entity) 这个类即是EF框架上下文信息,它会处理我们的所有和数据库相关的操作.代码如下:
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Web;
namespace MvcMusicStore.Models
{
public class MusicStoreEntities:DbContext
{
public DbSet<Album> Albums { get; set; }
public DbSet<Genre> Genres { get; set; }
}
}- 是不是很简单?只是通过继承DbContext 就可以实现所有数据库操作而没有复杂的接口等等,现在我们来添加一些初始数据到"数据库"用于撑起页面,包含一些流派 作者和专辑数据.
- 在http://mvcmusicstore.codeplex.com/中找到Code / Models / SampleData.cs并拖放到Models文件夹.
- 告诉EF 如何初始化数据库:打开global.asax,在Application_Start方法中添加如下代码:
protected void Application_Start()
{
System.Data.Entity.Database.SetInitializer(
new MvcMusicStore.Models.SampleData());
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}- 所有配置完成,测试一下吧.修改StoreController 使用真正的数据库(这里仅测试列表页):
MusicStoreEntities storeDB = new MusicStoreEntities();
//
// GET: /Store/
public ActionResult Index()
{
var genres = storeDB.Genres.ToList();
return View(genres);
}- 运行程序,浏览/store/将会看到刚才添加的数据里面的列表信息.
- 到这里,EF相关入门知识已经完毕.进入正题.
更新StoreController使用真正的数据库
在StoreController的浏览方法 Browse(string genre)中我们使用一个体裁名字作为查询关键字,我们只想要一个查询结果,所以我们想这样查询目标体裁:
不过,现在还不用着急写,稍后会介绍一个关键点.
.Single使用一个 Lambda 表达式作为参数,上一示例中,我们希望要名称和“Disco”相符的对象的第一个.
EF有一个机制允许我们预先加载外键相关对象,比如新闻 类型.新闻S, 类似于这种写法,这样可以降低访问数据库的次数.本实例中,我们想要加载体裁的同时加载该题材相关的相册,所以,我们有了如下写法:
{
// Retrieve Genre and its Associated Albums from database
var genreModel = storeDB.Genres.Include("Albums")
.Single(g => g.Name == genre);
return View(genreModel);
}
现在,我们来更新一下视图:
Views/Store/Browse.cshtml:
@{
ViewBag.Title = "Browse";
}
<h2>Browsing Genre: @Model.Name</h2>
<ul>
@foreach (var album in Model.Albums)
{
<li>
@album.Title
</li>
}
</ul>
看一下效果:
是不是很酷
现在再更新一下Detail吧:
// GET: /Store/Details/5
public ActionResult Details(int id)
{
var album = storeDB.Albums.Find(id);
return View(album);
}
看如下图的详细信息,是不是把真实的数据库信息查询到了.
有没有感觉到什么?
对,详细信息页直接输进来的,坑爹啊,现在就把查询结果加上链接:
Browse.cshtml :
@{
ViewBag.Title = "Browse";
}
<h2>Browsing Genre: @Model.Name</h2>
<ul>
@foreach (var album in Model.Albums)
{
<li>
@Html.ActionLink(album.Title,
"Details", new { id = album.AlbumId })
</li>
}
</ul>
预览:有没有一点感觉,我已经掌握EF+mvc了?放心吧 早着呢.
随笔感悟
公司新项目刚好要用MVC,虽然不是我们组负责,但是又记起来我的MVC,所以,继续翻起原来的博客,鼓起勇气,继续涨工资之路,本节主要介绍EF相关知识,如果有疑问可以去看一下这篇博客: http://www.asp.net/entity-framework,讲的非常细可以好好看看.要注意的是配置数据库连接的地方,可能有些不太友好.