EF实体框架之CodeFirst三
前两篇博客学习了数据库映射和表映射,今天学习下数据库初始化、种子数据、EF执行sql以及执行存储过程这几个知识。
一、数据库初始化策略
数据库初始化有4种策略
策略一:数据库不存在时重新创建数据库
Database.SetInitializer<EFCodeFirstDbContext>(new CreateDatabaseIfNotExists<EFCodeFirstDbContext>());
策略二:每次启动应用程序时创建数据库
Database.SetInitializer<EFCodeFirstDbContext>(new DropCreateDatabaseAlways<EFCodeFirstDbContext>());
策略三:模型更改时重新创建数据库
Database.SetInitializer<EFCodeFirstDbContext>(new DropCreateDatabaseIfModelChanges<EFCodeFirstDbContext>());
策略四:从不创建数据库
Database.SetInitializer<EFCodeFirstDbContext>(null);
其中,在使用每次启动应用程序时创建数据库DropCreateDatabaseAlways时,总是报错:无法删除数据库XXX,因为该数据库当前正在使用,这个错误找了半天,在一篇帖子上写让选中数据库,右键删除,只选关闭连接复选框,之后就可以了,我也试了下,是可以的。
二、种子数据
对于新建的数据库,可能会有一些默认的数据来做测试或默认配置,这时可以使用种子类来初始化数据库数据。加入使用的是DropCreateDatabaseAlways策略,那么初始化器类就要从该泛型类继承,并传入数据库上下文作为类型参数。接下来,要种子化数据库就要重写DropCreateDatabaseAlways类的Seed方法,而Seed方法拿到了数据库上下文,因此我们可以使用它来将数据插入数据库:
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using EFCodeFirstModels; namespace EFCodeFirstDataAccess
{
public class SeedingDataInitializer: DropCreateDatabaseAlways<EFCodeFirstDbContext>
{
protected override void Seed(EFCodeFirstDbContext context)
{
Person person = new Person("","cuiyanwei",SexType.Female,);
Person person1 = new Person("", "cuiyanwei1", SexType.Female, );
context.Persons.Add(person);
context.Persons.Add(person1);
base.Seed(context);
}
}
}
上面的代码中并没有SaveChanges(),然后将将数据库初始化器类用于数据库上下文类
public EFCodeFirstDbContext() : base("MyStrConn")
{
Database.SetInitializer<EFCodeFirstDbContext>(new SeedingDataInitializer());
}
此时初始化种子,就不能在OnModelCreating中执行数据库初始化策略了。
Database.SetInitializer<EFCodeFirstDbContext>(new DropCreateDatabaseAlways<EFCodeFirstDbContext>());
三、执行SQL语句
有时候在code first中也会执行sql来做查询,或者是查询视图。
//using能及时释放资源,例如数据库连接异常,可以即使将上下文释放
using (var db=new EFCodeFirstDbContext())
{
List<Person> persons= db.Database.SqlQuery<Person>("select * from Person where personId=@id",new SqlParameter("@id","")).ToList();
foreach (var person in persons)
{
Console.WriteLine("{0} {1} {2} {3}",person.PersonId,person.Name,person.Age,person.Sex);
}
}
Console.ReadLine();

然后在数据库中建一个视图TestView,不过查询的还是Person,其实也可以查询部分字段,那样还要再创建Model,因为懒所以还是使用Person。此时我们就不能使用DropCreateDatabaseAlways策略模式了,这样的话数据的视图这些都会不存在。我们可以使用CreateDatabaseIfNotExists策略模式,初始化数据时只需把SeedingDataInitializer类继承自CreateDatabaseIfNotExists就OK了。
//using能及时释放资源,例如数据库连接异常,可以即使将上下文释放
using (var db=new EFCodeFirstDbContext())
{
List<Person> persons= db.Database.SqlQuery<Person>("select * from TestView where personId=@id", new SqlParameter("@id","")).ToList();
foreach (var person in persons)
{
Console.WriteLine("{0} {1} {2} {3}",person.PersonId,person.Name,person.Age,person.Sex);
}
}
Console.ReadLine();

四、执行存储过程
有时候使用sql能解决的问题使用ef就不那么简单,比如查找树的某个节点的所有父节点或所有子节点。如果使用存储过程那就会很容易,不过存储过程也有弊端,例如只能返回一个表,不能同时返回多个表,可能是有我没找到吧。
CREATE PROCEDURE TestProcedure
@personId nvarchar()
AS
BEGIN
select * from Person where PersonId=@personId;
END
GO
上面创建一个有一个参数的存储过程,来查询person。
List<Person> persons = db.Database.SqlQuery<Person>("TestProcedure @personId", new SqlParameter("@personId", "")).ToList();
foreach (var person in persons)
{
Console.WriteLine("{0} {1} {2} {3}",person.PersonId,person.Name,person.Age,person.Sex);
}

上面的都是查询使用的都是SqlQuery,如果需要更新操作可以使用ExecuteSqlCommand方法。
int count= db.Database.ExecuteSqlCommand("update Person set Name=@name where PersonId=@personId",new[] { new SqlParameter("@name", "CYW"), new SqlParameter("@personId", "") });
Console.WriteLine(count);

从上面截图可以看到已经将personId=0003的Name改为CYW,之前都是cuiyanwei。
EF实体框架之CodeFirst三的更多相关文章
- EF实体框架之CodeFirst四
在EF实体框架之CodeFirst二中也提到数据库里面一般包括表.列.约束.主外键.级联操作.实体关系(E-R图).存储过程.视图.锁.事务.数据库结构更新等.前面几篇博客把表.存储过程.视图这些算是 ...
- EF实体框架之CodeFirst一
对于SQL Server.MySql.Oracle等这些传统的数据库,基本都是关系型数据库,都是体现实体与实体之间的联系,在以前开发时,可能先根据需求设计数据库,然后在写Model和业务逻辑,对于Mo ...
- EF实体框架之CodeFirst五
上一博客学习了下基本的约定配置,留下几个遗漏的,这篇就是学习下遗漏一复杂类型. 一.什么是复杂类型? 书中说道:“复杂类型也可视作值类型(?)可以作为附加属性添加到其他类.复杂类型与实体类型的区别在于 ...
- EF实体框架之CodeFirst二
在codefirst一中也说了Mapping是实体与数据库的纽带,model通过Mapping映射到数据库,我们可以从数据库的角度来分析?首先是映射到数据库,这个是必须的.数据库里面一般包括表.列.约 ...
- EF实体框架之CodeFirst七
前面的6篇博客基本把Code First学习的差不多了,今天这篇学习下code first中的并发控制和事务,基本也快学完了,顶多就差数据迁移. 在数据库中也是有锁和事务的概念,在C#中也是存在,当然 ...
- EF实体框架之CodeFirst六
上午的时候把复杂类型学习了一下,想着趁着周六日把Code First学习完,所以下午还是把Code First中的关系学习下.在数据库中最重要的恐怕就是E-R图了,E-R体现了表与表直接的关系.使用C ...
- EF实体框架之CodeFirst八
前面七篇基本把Code First学习了一下,不过code first中会出现一个问题,就是数据迁移的问题. 一.数据准备 还是在前面的demo上修改,这次使用Province和City类. publ ...
- 【MVC 1】MVC+EF实体框架—原理解析
导读:在之前,我们学过了三层框架,即:UI.BLL.DAL.我们将页面显示.逻辑处理和数据访问进行分层,避免了一层.两层的混乱.而后,我们又在经典三层的基础上,应用设计模式:外观.抽象工厂+反射,使得 ...
- 【EF 1】EF实体框架 原理+实例
一.知识回顾 到目前为止,自己学到的链接数据库操作已经经历了几个阶段,分别是:学生信息管理和(第一次)机房收费时的直接连接数据库操作表格,然后是机房个人重构中应用的操作实体,在其中还利用了一个很重要的 ...
随机推荐
- 以前写的关于Linux C/C++的博客
以前在CU写的关于Linux C/C++的博客 http://blog.chinaunix.net/uid/25909722/cid-24318-list-1.html
- 关于PHP中Session文件过多的问题
PHP的默认机制:每一次php请求,会有1/100的概率(默认值)触发“session回收”.如果“session回收”发生,那就会检查/tmp/sess_*的文件,如果最后的修改时间到现在超过了14 ...
- Java解决题目:有一对兔子,从出生第三个月起每个月都生一对兔子,小兔子长到第三个月后,每个月又生一对兔子。。。
题目:有一对兔子,从出生第三个月起每个月都生一对兔子,小兔子长到第三个月后,每个月又生一对兔子,假如兔子都不死,问M个月时兔子的数量,M为键盘读入的正整数.(请用Java语言作答) 样例输入: 3 样 ...
- html不使用cache数据
<HEAD> <META HTTP-EQUIV="Pragma" CONTENT="no-cache"> &l ...
- 教你一招 - Misc类型插件的妙用(附带插件源码)
熟悉nopcommerce插件的朋友应该知道里面有一种Misc类型的插件,比如Nop.Plugin.Misc.WebServices和 Nop.Plugin.Misc.FacebookShop,继承自 ...
- 【温故而知新-Javascript】比较 undefined 和 null 值
JavaScript 中有两个特数值: undefined和null,在比较它们的时候需要留心.在读取未赋值的变量或试图读取对象没有的属性时得到的就是 undefined 值. <!DOCTYP ...
- python中的getattr函数
getattr(object, name[, default]) -> value Get a named attribute from an object; getattr(x, 'y') i ...
- UVA 12382 Grid of Lamps --贪心+优先队列
题意:给出每行每列至少有的灯泡数,问最少有的灯泡数. 解法:要使灯泡数尽量小,说明要使交叉点尽量多,这样即抵了行,又抵了列,为最优的.所以可以用行来消去列,也可以用列来消去行,我这里是列来消去行.首先 ...
- AC日记——codevs 1086 栈 (卡特兰数)
题目描述 Description 栈是计算机中经典的数据结构,简单的说,栈就是限制在一端进行插入删除操作的线性表. 栈有两种最重要的操作,即pop(从栈顶弹出一个元素)和push(将一个元素进栈). ...
- C++学习之开发环境搭建篇(一)
由于C++是一门非跨平台语言,其开发的程序编译生成的可执行文件,只能在相应的操作系统中被执行,离开此系统环境将无法执行. 主要原因是不同的操作系统,可执行文件的结构不同,最为常见的操作系统是有:MAC ...