MVC学习日记(三)EntityFramework
其实学会了第一篇的创建和第二篇的使用以后,基本的mvc操作足够了,至于验证神马的,还不如用Jquery、h5的好看适用,所以接下来, 后续上会讲一些比较实用的。
在之前的文章说到了基础的使用, 那么,如何让你的MVC程序,活起来呢? 这就必须要连接数据库了, 我所了解的有两种方法, 一种是我们熟知的映射模型,通过反射
得到数据库的结构模型,使用表生成器,讲对应的表反射出来,然后用Sql操作语句 , 操作对象。 另一种呢, 就是微软包里面的一款强大工具 EntityFramework了,
同样, EntityFramework 是一个数据库反射操作的模型,但是,机制上已经被编写, 可以很快速的使用,使用linq语句,可以数据库的限制,非常的实用(尤其是中下型项目),
接下来, 和大家介绍EF常见的三种创建模式。
第一种DataFirst , 数据优先创建模式, 和字面意思一样, 这样建立的EF模型,必须先有数据库。
为你的MVC项目,添加一个EF模型, 右键你的MVC项目 起个名字, 通常以XXXX Content结尾,(别问为什么,因为约定优先原则)
点击添加以后, 会自动让你选择模型, 左边的是database 数据优先 , 右边那个下面再说
选完连接方式, 接下来就是配置数据库的连接, 连接一下,没有连接过, 就New Connection... 按步骤走就是了
生成出来的东西都在 .edmx文件里面, 一个 .context.cs 文件,里面就是操作的关键
.cs 文件,里面的类模型, 和数据库里面数据表一一对应。
这就是数据优先的EF模型 ,那么 下面看看如何操作
比如设定一个 PersonController
里面的方法
var db = new AdventureWorkEntities(); //上下文类操作对象, 用于操作EF模型的
Public ActionResult Index()
{
List<Person> persons = from p in db.Person select p ;
}
View 上,
using 命名空间.Person类
@model 命名空间.Person类
@foreach(Person p in Model)
{
<p>
@p.name
@p.age
</P>
}
手打的, 大致思路, 大家参考, 多练习,会熟练的。
接下来叙述一下EntityFramework里的第二种方式,ModelFirst, 就是模型优先的原则, 顾名思义, 就是先建立模型, 关系,再生成数据库, 没错, 就EF帮你生成数据库, 你本人无需建立数据库。
开始一样, 到了这个时候,选右边的EntityModel, 这时候建立的就是一个Model优先的EF了
对应的,出现一张可操作的模型视图, 可以右键操作, 添加Model模型, 可以更新/添加数据库。
添加方式Model的方式也很简单, 以实体为操作对象,基本上按步骤走, 就能实现了, 和datafirst有很多类似。但是性能上,比datafirst要高,毕竟,优先级不一样了, 操作也不一样了。
最后一种codefirst是 3 之后出现的, 一种效率更高, 但是更新更麻烦的一种方式, 具体优劣, 看具体应用环境。
这种模式很好的解析了EF的运作过程
namespace CodeFirst { public class Order { public int Id { get; set; } public string Customer { get; set; } public System.DateTime OrderDate { get; set; } public virtual List<OrderDetail> OrderDetails { get; set; } } }
using System; using System.Collections.Generic; namespace CodeFirst { public partial class OrderDetail { public int Id { get; set; } public string Product { get; set; } public string UnitPrice { get; set; } public int OrderId { get; set; } public virtual Order Order { get; set; } } }
建立实体类, 反射的基础对象类
有了这两个类之后让我们定义一个数据库上下文,有了它我们就可以对数据进行增删改查操作了,这个类必须继承于"System.Data.Entity.DbContext”类以赋予它数据操作能力。因此接下来我们需要给这个应用安装EntityFramework包,因为到目前为止我们并没有引入EF框架相关的任何内容,我们需要引入EF相关程序集。但是我们有更好的选择那就是NuGet。通过NuGet进行在线安装:项目中右键选择"Manage NuGet Packages…”;选择Online;再选择“EntityFramework”;然后点击安装即可。不了解NuGet的朋友到这里看一下使用 NuGet 管理项目库。数据库上下文操作类:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Data.Entity; namespace CodeFirst { public class OrderContext:DbContext { public DbSet<Order> Orders { get; set; } public DbSet<OrderDetail> OrderDetails { get; set; } } }
然后我们进行测试,在这个类中我们首先创建了一个Order实例,接着编码查询:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace CodeFirst { class Program { static void Main(string[] args) { using (var ctx = new OrderContext()) { var o = new Order(); o.OrderDate = DateTime.Now; ctx.Orders.Add(o); ctx.SaveChanges(); var query = from order in ctx.Orders select order; foreach (var q in query) { Console.WriteLine("OrderId:{0},OrderDate:{1}", q.Id, q.OrderDate); } Console.Read(); } } } }
如果是第一次使用EF Code First的朋友一定会有疑问,我们没有进行任何数据库配置,增加了一条数据通过查询确实保存上了,那么我们的数据到底在哪呢?事实上如果用户不进行数据库配置EF默认会使用“.\SQLEXPRESS”数据库实例,如果你没有安装“.\SQLEXPRESS”则默认使用LocalDb,关于LocalDb的具体细节请看:SQL Server 2012 Express LocalDB,例如我本机就存放在:“C:\Users\Kenshin”,可以看到创建了一个名为“CodeFirst.OrderContext”的数据库:
但是多数情况下我们是希望自己控制这个数据库的,例如我想让他保存在我机器上的”.\SQL2008”实例上,此时我们就需要在配置文件App.Config中配置一个数据库连接串,然后在我们的数据库上下文中指定这个连接名称。
配置文件:
<?xml version="1.0" encoding="utf-8"?> <configuration> <configSections> <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --> <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=4.4.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /> </configSections> <connectionStrings> <add name="CodeFirstDb" connectionString="Data Source=.\SQL2008;Database=CodeFirstDb;UID=sa;PWD=123;" providerName="System.Data.SqlClient"></add> </connectionStrings> <entityFramework> <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework"> <parameters> <parameter value="v11.0" /> </parameters> </defaultConnectionFactory> </entityFramework> </configuration>
OrderContext类,构造函数多了一个连接名参数:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Data.Entity; namespace CodeFirst { public class OrderContext:DbContext { public OrderContext(string connectionName) : base(connectionName) { } public DbSet<Order> Orders { get; set; } public DbSet<OrderDetail> OrderDetails { get; set; } } }
使用的时候,传入配置的数据库连接字符串名称:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace CodeFirst { class Program { static void Main(string[] args) { using (var ctx = new OrderContext("CodeFirstDb")) { var o = new Order(); o.OrderDate = DateTime.Now; ctx.Orders.Add(o); ctx.SaveChanges(); var query = from order in ctx.Orders select order; foreach (var q in query) { Console.WriteLine("OrderId:{0},OrderDate:{1}", q.Id, q.OrderDate); } Console.Read(); } } } }
执行之后就会发现在”.\SQL2008”实例上多了一个“CodeFirstDb”数据库(注意图中除了我们创建的两个实体表还有一个系统表dbo._MigrationHistory它记录了模型的定义,在以后的文章中我会着重解释此表):