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实体框架 原理+实例
一.知识回顾 到目前为止,自己学到的链接数据库操作已经经历了几个阶段,分别是:学生信息管理和(第一次)机房收费时的直接连接数据库操作表格,然后是机房个人重构中应用的操作实体,在其中还利用了一个很重要的 ...
随机推荐
- window10系统安装oracle11g时遇到INS-13001环境不满足最低要求
机器安装了window10系统,之前有次安装oracle11g是成功了.但是机器后来固态硬盘坏了,又坏了个后,还是win10系统安装oracle11g时,出现INS-13001环境不满足最低要求,郁闷 ...
- kettle初探
Kettle是Pentaho的一个组件,主要用于数据库间的数据迁移,到我用过的4.2版,还不支持noSQL,不知道4.4是不是支持了. Kettle自己有三个主要组件:Spoon,Kitchen,Pa ...
- 微信公众平台应用开发:方法、技巧与案例--柳峰,Java语言版本
他本人的博客:http://blog.csdn.net/lyq8479 作者简介: 刘运强,网名“柳峰”,资深微信公众平台应用开发工程师,国内微信公众平台应用开发的先驱之一,项目经验丰富.他还是一位资 ...
- Python Backup Files
近来书写 Python 脚本进行替换以前的 shell 脚本,发现 Python 优于 shell 的最直观的一点Python 结构明了,可读性高(本人认为)在此做一些记录 本次记录利用 Python ...
- Google 以图搜图 - 相似图片搜索原理 - Java实现
前阵子在阮一峰的博客上看到了这篇<相似图片搜索原理>博客,就有一种冲动要将这些原理实现出来了. Google "相似图片搜索":你可以用一张图片,搜索互联网上所有与它相 ...
- Windows 系统下json 格式的日志文件发送到elasticsearch
Windows 系统下json 格式的日志文件发送到elasticsearch配置 Nxlog-->logstash-->ElasticSearch Logstash https://ww ...
- poj 3169 Layout 差分约束模板题
Layout Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 6415 Accepted: 3098 Descriptio ...
- 使用NDK c++建立一个Android应用
使用NDK c++建立一个Android应用 一.工具 ADT(集成了eclipse,cdt,ndk plug-in) NDK (用它来编译c/c++程序) JDK (Java开发包) ANT(ecl ...
- (三)openwrt主Makefile解析
本周成胖子每周一博到了第四周^_^ 前言 主Makefile结构 顶层 第二层 尾记 前言 前一篇,我们大概描述了整个镜像文件的生成过程.本周我们来解析主Makefile,看看主要编译过程是怎么产生的 ...
- Hadoop question list
1.我们在开发普通的web app的时候,总会用到orm框架,如hibernates ,ibates等,在hadoop中我们一直使用writable对象,当然如果我们想实现自己的对象类,需要继承这个w ...