前两篇博客学习了数据库映射和表映射,今天学习下数据库初始化、种子数据、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。

最新文章

  1. PHP 批量生成静态文件目录代码
  2. Ajax 是什么?Ajax 的交互模型?同步和异步的区别?如何解决跨域问题?以及 HTTP状态码
  3. 《深入理解bootstrap》读书笔记:第二章 整体架构
  4. 洛谷P1262 间谍网络
  5. C++primer学习笔记(二)&mdash;&mdash;Chapter 4
  6. 初步探讨WPF的ListView控件(涉及模板、查找子控件)
  7. vmware产品
  8. 软件测试software testing summarize
  9. 关于UIView 的autoresizingMask属性,即UIViewAutoresizing
  10. Python 基础编程
  11. 关于JQuery Class选择器的一点
  12. esay-ui学习笔记(一)
  13. 20190316xlVba_设置行高的改进方案
  14. python3配置 opencv
  15. 牛客国庆集训派对Day5 数论之神
  16. (惊艳)基于谷底最小值的阈值的图像分割(改进HSV中的H分量可以用imhist(H)提取)
  17. JMeterPlugins插件监听器学习-监听器
  18. 【BZOJ2589】 Spoj 10707 Count on a tree II
  19. 关于网站中Logo部分的写法
  20. 雷林鹏分享:Ruby 循环

热门文章

  1. DevExpress GridControl使用方法总结(转)
  2. SqlBulkCopy块拷贝数据时,不履行触发器和束缚 解决办法
  3. Linux学习之四——磁盘与文件系统管理
  4. runc kill 和 delete流程分析
  5. CentOS安装Hypernetes相关问题解法
  6. ZBrush中的SubTool工具该怎样使用
  7. Codeforces Round #258 D Count Good Substrings --计数
  8. MATLAB基本命令
  9. ZIP文件伪加密
  10. ArcGis 获取地理、平面坐标系