2.5 添加数据访问

视频下载: 1 2

目录:

---------------------------------------------------------

  1. 技术介绍
  2. 使用 Entity Framework Code-First 进行数据访问
  3. 修改我们的模型类
  4. 在 Web.config 中查看数据库连接串
  5. 增加上下文类
  6. 增加我们的商店分类数据
  7. 查询数据库
  8. 更新 Index Action 查询数据库
  9. 使用数据库中的数据更新浏览和明细页面

---------------------------------------------------------    

      上一次,我们使用了模拟的数据从控制器发送到视图模板。现在,我们开始使用真正的数据库,在这个教程中,我们将指导如何使用LocalDB数据库。

当然,你还可以使用熟悉的 SQL Server 数据库。

1.技术介绍

(1)LocalDB

      随着SQL Server 2012的发布,LocalDB跃入我们的视线,它可以被看做是SQL Server Express的轻量级版本。LocalDB专门为开发人员创建,它非常易于安装,几乎无需管理,兼容T-SQL语言,编程接口与SQL Server Express别无二致。有了LocalDB,开发人员就不需要在自己的笔记本上安装和维护一个庞大的SQL Server实例了。另外,LocalDB也适用于小型应用环境,开发人员可以将其用于小型生产环境或者嵌入式环境。

      说了这么多,现在让我们来看看LocalDB的核心技术特性:

  • 兼容其它SQL Server版本,使用sqlservr.exe作为服务进程,使用相同的客户端访问接口(如ADO.NET、ODBC或PDO),兼容T-SQL编程语言。
  • 在同一台计算机上不必安装多个LocalDB,不同的应用程序可以并行执行多个LocalDB进程,但所有的进程都是从同一个可执行文件(sqlservr.exe)启动的。
  • LocalDB不会创建任何系统服务,LocalDB进程会根据需要自动启动、停止。应用程序只需连接“Data Source=(localdb)\v11.0”,LocalDB就会作为应用程序的子进程启动。随着连接的终止,LocalDB进程也会随之停止。
  • LocalDB支持AttachDbFileName属性,允许开发者指定数据库文件位置。例如:
Data Source = (localdb)\v11.0;  
Integrated Security = true;  
AttachDbFileName = C:\MyData\Database1.mdf 

      LocalDB作为一个功能丰富的轻量级数据库,绝对值得我们去尝试。 

(2)Entity Framework 5

      在开发面向数据的软件时我们常常为了解决业务问题实体、关系和逻辑构建模型而费尽心机,ORM的产生为我们提供了一种优雅的解决方案。ADO.NET Entity Framework是.NET开发中一种由ADO.NET驱动的ORM(Object Relational Mapping)框架,使用Entity Framework开发人员可以不必考虑数据的基础数据表和列,在处理数据时能够以更高的抽象级别进行工作,并能够以相对传统开发编写更少的代码来创建和维护应用程序。

      我们知道面向对象的编程与数据存储系统的交换提出了一个难题:类结构通常同关系数据表组织结构相近但又不同。例如数据中可能使用一个外键表示一个实体与另一个实体的关系,但是对于类而言我们通知会在类中定义一个属性来描述这种关系。对于这个问题当前ORM框架一般选择通过将面向对象的类和属性映射到关系表和列来弥补这种不足。但是Entity Framework并没有采取这种方式而是将逻辑模型中的表、列和外键约束映射到概念模型中的实体和关系,实体数据模型工具再基于概念模型生成可扩展的数据类。这些类派生自基类,而基类提供服务以将实体具体化为对象并进行跟踪和保存。这样一来开发人员不仅可以很方便的对数据类进行扩展而且可以像处理关联对象一样处理实体和关系。

      Entity Framework支持“Database First”、“Model First”和“Code First”三种编程方式。“Database First”模式我们称之为“数据库优先”,前提是你的应用已经有相应的数据库,你可以使用EF设计工具根据数据库生成数据数据类,你可以使用Visual Studio模型设计器修改这些模型之间对应关系。Model First我们称之为“模型优先”,这里的模型指的是“ADO.NET Entity Framework Data Model”,此时你的应用并没有设计相关数据库,在Visual Studio中我们通过设计对于的数据模型来生成数据库和数据类。Code First模式我们称之为“代码优先”模式,是从EF4.1开始新建加入的功能。使用Code First模式进行EF开发时开发人员只需要编写对应的数据类(其实就是领域模型的实现过程),然后自动生成数据库。这样设计的好处在于我们可以针对概念模型进行所有数据操作而不必关心数据的存储关系,使我们可以更加自然的采用面向对象的方式进行面向数据的应用程序开发。

2. 使用 Entity Framework Code-First 进行数据访问

      我们将使用包含在 ASP.NET MVC4 中的 Entity Framework (EF) 支持进行查询和更新数据库中的数据。EF 是一个灵活的进行数据访问的对象关系映射 API,允许开发人员使用面向对象的方式对数据库中的数据进行查询和更新。

      Entity Framework 5 支持一种称为代码优先的开发模式,代码优先允许你通过编写简单的类来创建模型对象(也被称为 POCO, 简单的,老的 CLR 对象),然后通过类来创建数据。注意,需要在你的项目中引用程序集 EntityFramework,在你安装 Entity Framework 的文件夹中可以找到这个程序集。

3. 修改我们的模型类

      我们将延后数据库的创建工作,在完成这个任务之前,我们先修改我们得模型类,增加我们需要的内容。

(1)增加艺术家 Artist 类

      我们的专辑将要关联到艺术家,所以,我们需要增加一个简单的类来描述艺术家,增加一个新的名为 Artist 的类。

namespace MvcMusicStore.Models 
{
public class Artist
{
public int ArtistId { get; set; }
public string Name { get; set; }
}
}

(2)更新现有的模型类

namespace MvcMusicStore.Models 
{
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; }
}
}

      然后更新 Genre 类。

namespace MvcMusicStore.Models
{
public class Genre
{
public int GenreId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public List<Album> Albums { get; set; }
}
}

4. 在 Web.config 中查看数据库连接串

      我们需要在网站的配置文件中增加一些行,以便 Entity Framework 知道如何连接到我们的数据库,双击 Web.config 文件。

      找到 <connectionStrings> 的配置节,修改默认代码如下:

<connectionStrings>
<add name="MusicStoreEntities" providerName="System.Data.SqlClient"
         connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=MvcMusicStore;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\MvcMusicStore.mdf" />
</connectionStrings>

      注意,这里数据库连接串的名称很重要,以后使用 EF Code-First 的时候,通过它来找到数据库,这里的链接串中使用了 AttachDBFilename=|DataDirectory|\MvcMusicStore.mdf,这里的 DataDirectory 指的就是项目中的 App_Data 文件夹。

5. 增加上下文类

      在Models文件夹上右键点击,然后,增加一个新的名为 MusicStoreEntities.cs 的文件。 需要注意的是,这个类的名称必须与数据库连接串的名称一致。

      这个类将反映 Entity Framework 数据库的上下文,用来处理创建,读取,更新和删除的操作,代码如下所示:

复制代码
using System.Data.Entity; namespace MvcMusicStore.Models 
{
public class MusicStoreEntities:DbContext
{
public DbSet<Album> Albums { get; set; }
public DbSet<Genre> Genres { get; set; }
public DbSet<Artist> Artists { get; set; }
}
}
复制代码

      注意,这里使用了 System.Data.Entity 命名空间。记得要 using 一下。 

      不需要其他的配置,特定的接口等等,通过扩展 DbContext 基类,我们得 MusicStoreEntities 类就可以处理我们对数据库的操作了,现在,我们就开始,先为我们的类增加一些属性来从数据库获取额外的信息。 

6. 增加我们的商店分类数据

      对于 Code First 来说,我们首先定义模型,然后通过模型来创建数据库,甚至也不需要写 Insert 语句,我们可以通过标准的 C# 代码来创建表中的记录。

      我们先通过一些种子数据通过 Entity Framework 为新创建的数据库增加一些数据。先创建我们的商店分类,这需要通过一个 Genres 的列表完成,还有专辑。下载SampleData.cs文件,在该文件中已经包含了用来简单地创建数据的文件,将它加入到 Models 文件夹中,如下所示。

       现在,我们需要增加一些代码来告诉 Entity Framework 关于 SampleData 类的事情。双击 Global.asax 文件,打开它,在 Application_Start 方法中,增加如下的行。Application_Start()方法是在Asp.net应用程序第一次启动时会启动该事件。

复制代码
// 一般用来进行网站的初始化 
protected void Application_Start()
{
System.Data.Entity.Database.SetInitializer(new MvcMusicStore.Models.SampleData());
AreaRegistration.RegisterAllAreas();
    WebApiConfig.Register(GlobalConfiguration.Configuration);
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);
}
复制代码

      这个方法用来初始化数据库,然后填充一些数据。当DbContext被实例化时这个数据库初始化策略将被调用。初始化策略可以选择检查数据库是否存在,创建一个新的数据库,用数据填充数据库。默认的策略是DropCreateDatabaseIfModelChanges类的一个实例,这个实例包含用户填充数据集合。

      这样,我们就完成了配置 Entity Framework 的工作。

7. 查询数据库

      现在,我们更新一下我们的 StoreController 以便取代以前模拟的数据,通过调用我们的数据库来查询实际数据。我们先在StoreController中定义一个字段来访问我们的 MusicStoreEneities 类的对象实例,它命名为 storeDB。

using MvcMusicStore.Models;
namespace MvcMusicStore.Controllers
{
public class StoreController : Controller
{
MusicStoreEntities storeDB = new MusicStoreEntities();
…………

8.更新 Index Action 查询数据库

      MusicStoreEntities 类通过 Entity Framework 提供了数据库中数据表的集合,更新一下 StoreController 的 Index Action 方法来获取全部的分类数据。我们原来使用硬编码的数据,现在,我们可以使用 Entity Framework 的 Generes 集合来取代它了。

      对于 EF 的使用,我建议你了解一下 Repository 模式。

复制代码
// // GET: /Store/ 
public ActionResult Index()
{
var genres = storeDB.Genres.ToList();
return this.View( genres );
}
复制代码

       对于视图模板不需要任何修改,我们仍然返回同样的 Store Index View Model 。

      运行程序,访问 /Store 地址的时候,我们现在可以看到数据库中分类的列表。

 9. 使用数据库中的数据更新浏览和明细页面

      当在首页通过 /Store/Browse?genre=[some-genre] 链接访问 Browse 这个 Action 的时候,我们需要通过流派的名称来获取相应的专辑,对于我们的音乐店来说,每个流派的名称是唯一的,可以通过 LINQ 中的 Single 扩展方法来获取查询结果中的唯一的流派对象。

var example = storeDB.Genres.Single(g => g.Name == “Disco”);

      Single 方法使用一个 Lambda 表达式作为参数,表示我们希望获取匹配指定值的单个流派对象,在上面的例子中,我们将会获得名为Disco的流派对象。

      通过EF,在获得流派对象的同时,我们还可以获取流派相关的对象,例如属于这个流派的专辑集合,我们可以提前获取相关的专辑信息,这就需要我们修改一下上面的查询,包含专辑信息。通过 Include 方法可以指定我们希望获取的相关信息,这种方式非常有效,这样,我们就可以在一次数据访问中,既可以获取流派对象,也可以同时获取相关的专辑对象。

      这样更新之后,我们的 Action 方法将会成为下面的样子。

// /Store/Browse?genre=DISCO
public ActionResult Browse( string genre ) 
{
var genreModel = storeDB.Genres.Include("Albums").Single(g => g.Name == genre);
return this.View(genreModel);
}

      注意,在流派 Genre 的属性中有一个名为 Albums 的集合属性。

      然后,我们可以更新一下 Store 的 Browse 视图来显示相应的专辑,打开视图模板,增加一个列表。

@model MvcMusicStore.Models.Genre
@{
ViewBag.Title = "Browse";
}
<h2>Browsing Genre: @Model.Name</h2>
<ul>
@foreach (var album in Model.Albums)
{
<li>@album.Title</li>
}
</ul>

      运行程序,浏览 /Store/Browse?genre=Jazz,现在就可以看到保存在数据库中的的专辑数据了。

      同样,我们还可以修改一下 Details ,通过传递的参数来获取专辑对象。修改后的方法如下所示。

// /Store/Details/5
public ActionResult Details(int id)
{
var album = storeDB.Albums.Find(id);
return View(album);
}

      运行程序,访问 /Store/Details/1,应该可以看到下面的内容。

      我们更新一下 Browse 视图,提供链接到明细页面的超级链接,这里,我们使用 ActionLink 方法,修改后的视图如下所示。

      再次浏览 Browse 的时候,每个专辑应该已经成为了一个链接,如图所示:

posted @ 2015-09-16 18:28  RunningYY  阅读(533)  评论(0)    收藏  举报