1、Code First 启用存储过程映射实体 

1 protected override void OnModelCreating(DbModelBuilder modelBuilder)
2 {
3 base.OnModelCreating(modelBuilder);
4 modelBuilder.Entity<Destination>().MapToStoredProcedures();
5 }

2、接管自己的Transaction,实现高度自定义

1 DbContext db = new DbContext();
2 db.Database.BeginTransaction();

3、三种实体加载模式EagerLoad(预加载),LazyLoad(延迟加载),ExplicitLoading(手动加载)

1 DbContext db = new DbContext();
2 db.Table1.Include(d=>d.Table2);//预加载
3
4  public class EntityTable
5  {
6    public virtual EntityTable2 ForeignKeyTable { get; set; } //使用virtual实现延迟加载
7  }
8
9 dbContext.Entry(YouSelectModel).Collection(t => t.References).Load();//显式手动加载

4、Code First自定义存储过程调用

1 public virtual int sp_test_delete(Nullable<int> id)
2 {
3 var idParameter = id.HasValue ?
4 new ObjectParameter("id", id) :
5 new ObjectParameter("id", typeof(int));
6
7 return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("sp_test_delete", idParameter);
8 }

5、DbContext对象追踪

1 DbContext db = new DbContext();
2 db.ChangeTracker.Entries(); //获取所有的实体
3 db.Table1.Local;//获取某张表下状态为修改或者增加的状态,注意不能追踪删除状态的实体
4 db.Table1.AsNoTracking().ToList();//这样查询出来的数据,DbContext将不会追踪,修改后,SaveChanges不会更新到数据库

6、Entity Framework的仓储模式提供的Find方法

1 DbContext db = new DbContext();
2 db.Table1.Find(20);//这个方法是仓储模式提供的,没有用到IQuerable提供的扩展方法,不会

7、重写ShouldValidateEntity和ValidateEntity实现Entity Framework自定义模型验证

 1             protected override bool ShouldValidateEntity(DbEntityEntry entityEntry)//返回实体是否需要验证
2 {
3 return base.ShouldValidateEntity(entityEntry);
4 }
5 protected override DbEntityValidationResult ValidateEntity(DbEntityEntry entityEntry, IDictionary<object, object> items)//实体的自定义验证方法,此为验证学生实体姓名不能为abc
6 {
7 List<DbValidationError> error = new List<DbValidationError>();
8 if (entityEntry.Entity is Student)
9 {
10 if ((entityEntry.Entity as Student).Name == "abc")
11 {
12 error.Add(new DbValidationError("Name", "不能为abc"));
13 }
14 }
15 if (error.Count > 0)
16 {
17 return new DbEntityValidationResult(entityEntry, error);
18 }
19 else
20 {
21 return base.ValidateEntity(entityEntry, items);
22 }
23 }

8、实现Interception来截获EF底层执行的SQL语句,也可以使用这个拦截器实现读写分离

 1         /// <summary>
2 /// SQL命令拦截器
3 /// </summary>
4 public class NoLockInterceptor : IDbCommandInterceptor
5 {
6 public void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
7 {
8 throw new NotImplementedException();
9 }
10
11 public void NonQueryExecuted(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
12 {
13 throw new NotImplementedException();
14 }
15
16 public void ReaderExecuted(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
17 {
18 throw new NotImplementedException();
19 }
20
21 public void ScalarExecuted(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
22 {
23 throw new NotImplementedException();
24 }
25
26 public void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
27 {
28
29 }
30
31 public void ScalarExecuting(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
32 {
33
34 }
35 }

  然后在程序启动时执行以下代码来实现监控

System.Data.Entity.Infrastructure.Interception.DbInterception.Add(new NoLockInterceptor());

  或者在配置文件中增加interceptors节点,下面增加interceptor

1   <entityFramework codeConfigurationType="MySql.Data.Entity.MySqlEFConfiguration, MySql.Data.Entity.EF6">
2 <interceptors>
3 <interceptor type="ConsoleApp2.abc.NoLockInterceptor,ConsoleApp2"></interceptor>//格式是全部命名空间加类名,然后逗号,命名空间的首个节点,这里我也没明白为什么这么写,C#好多配置文件都这么配置的
4 </interceptors>
5 <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
6 <providers>
7 <provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6" />
8 </providers>
9 </entityFramework>

9、code first 的 3种对象关系,one to one 、one to multi、 multi to multi

  one to one 1对1,1个学生对应1个学生地址,1个学生地址对应1个学生,可能1个学生下没有学生地址

 1         public class Student
2 {
3 [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
4 public int ID { get; set; } 7 public virtual StudentAddress StudentAddress{ get; set; } //关键
8 }
9 public class StudentAddress
10 {
11 [Key,ForeignKey("Student")] //关键
12 public int ID { get; set; }14 public virtual Student Student{ get; set; }
15 }

  one to multi 一对多,一个学生地址下可能有多个学生,1个学生只能有一个学生地址

 1         public class Student
2 {
3 [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
4 public int ID { get; set; }
5 public virtual StudentAddress StudentAddress { get; set; } //关键
6
7 }
8
9 public class StudentAddress
10 {
11 [Key] //注意这里
12 public int ID { get; set; }
13
14 public virtual ICollection<Student> Destination { get; set; } //关键
15 }

  multi to multi 多对多,1个学生下可能有多个地址,1个地址也可能有多个学生

 1         public class Student
2 {
3 [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
4 public int ID { get; set; }
5 public virtual ICollection<StudentAddress> StudentAddress { get; set; } //关键
6
7 }
8
9 public class StudentAddress
10 {
11 [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] //注意这里有不一样的地方
12 public int ID { get; set; }
13
14 public virtual ICollection<Student> Destination { get; set; } //关键
15 }

10、使用DataAnnotations来修改默认协定

  Key 主键

  Timestamp 设置并发时间戳

  ConcurrencyCheck 设置当前字段参与开放式并发校验

  Required 设置字段非空

  MaxLength 设置字符串的最大长度

  MinLength 设置字符串的最小长度

  Table 设置实体对应数据库表的名称

  Column 设置字段对应数据库表字段的名称

  ForeignKey 设置外检

  NotMapped 这个字段不生成在数据库表中,不用于生成sql

11、Fluent api配置  

 1 protected override void OnModelCreating(DbModelBuilder modelBuilder)
2 {
3 var studentConfig = modelBuilder.Entity<Student>();
4 studentConfig.ToTable("StudentDetail");//修改当前实体对应的表名
5 studentConfig.Map<Student>(d=> //Map自定义表的schame,常用于将一个实体生成两个表
6 {
7 d.Properties(p=>new { p.StudentId,p.StudentName });//设置当前实体需要映射表字段的列
8 d.ToTable("StudentDetail"); //设置当前表对应数据库的名称
9 }).Map(Student>(d=>
10 {
11 d.Properties(p=>new { p.StudentId,p.Address });//设置当前实体需要映射表字段的列
12 d.ToTable("StudentDetail2"); //设置当前表对应数据库的名称
13 });
14 studentConfig.Property(d=>d.StudentName).HasColumnName("NewTable").HasMaxLength(100).IsRequired();//给字段设置名字和最大长度和必填
15 }

  这样,一个表的Fluent Api可能有很多,一个数据库如果几百张表那么可能会有很多这个设置的代码,全部在DbContext忠会很多

  可以这样分离  

 1 public class StudentConfiguration : EntityTypeConfiguration<Student>
2 {
3 public StudentConfiguration()
4 {
5 this.ToTable("NewTable");
6 }
7 }
8 //这样可以把Fluent Api分离到多个文件中
9 //然后在DbContext中的OnModelCreating中增加
10 modelBuilder.Configurations.Add(new StudentConfiguration());

12、Code First的初始化策略 IfNotExists,IfModelChanges,Always,Custom  

1          Database.SetInitializer<SchoolDBEntity>(new CreateDatabaseIfNotExists<SchoolDBEntity>());     //创建数据库,如果数据库未存在
2 Database.SetInitializer<SchoolDBEntity>(new DropCreateDatabaseIfModelChanges<SchoolDBEntity>()); //删除数据库后重新创建
3 Database.SetInitializer<SchoolDBEntity>(new DropCreateDatabaseAlways<SchoolDBEntity>());//每次运行程序都会删除数据库重新创建
4 Database.SetInitializer<SchoolDBEntity>(new NullDatabaseInitializer<SchoolDBEntity>()); //禁用数据库初始化策略

  使用中自定义的初始化器,但是基本上也是只能在创建完毕后,加入初始化数据

 1 public class MyCreateDatabaseIfNotExists: CreateDatabaseIfNotExists<BreakAwayContext>
2 {
3 public override void InitializeDatabase(BreakAwayContext context)
4 {
5 base.InitializeDatabase(context);
6 }
7 protected override void Seed(BreakAwayContext context)
8 {
9 Console.WriteLine("数据库创建完毕,可以创建初始化数据");
10 base.Seed(context);
11 }
12 }

13、使用Migration进行无缝迁移

  1、启用Migration

    enable-migrations

  2、项目启动时运行以下代码,来实现自动迁移   

1 Database.SetInitializer(new MigrateDatabaseToLatestVersion<BreakAwayContext, Migrations.Configuration>());

  3、如果不使用自动迁移则使用 update-database来修改数据库

14、使用Entity Framework Profiler监控EF生成的语句

  1、安装EfProf

  2、引入HibernatingRhinos.Profiler.Appender

    后在代码中执行以下语句,来截获EF的各种sql

    HibernatingRhinos.Profiles.Appender.EntityFramework.EntityFrameworkProfiler.Initialze();

  3、打开EfProf 来检测生成执行的语句

EntityFramework 常见用法汇总的更多相关文章

  1. curl命令常见用法汇总 good

    curl是一种命令行工具,作用是发出网络请求,然后得到和提取数据,显示在"标准输出"(stdout)上面. curl是一个强大的命令行工具,它可以通过网络将信息传递给服务器或者从服 ...

  2. pip常见用法汇总

    1.pip安装 yum -y install epel-release && yum -y install python-pip 2.pip安装软件 (1)安装单个软件:pip ins ...

  3. Linux中find常见用法

    Linux中find常见用法示例 ·find   path   -option   [   -print ]   [ -exec   -ok   command ]   {} \; find命令的参数 ...

  4. php中的curl使用入门教程和常见用法实例

    摘要: [目录] php中的curl使用入门教程和常见用法实例 一.curl的优势 二.curl的简单使用步骤 三.错误处理 四.获取curl请求的具体信息 五.使用curl发送post请求 六.文件 ...

  5. Guava中Predicate的常见用法

    Guava中Predicate的常见用法 1.  Predicate基本用法 guava提供了许多利用Functions和Predicates来操作Collections的工具,一般在 Iterabl ...

  6. find常见用法

    Linux中find常见用法示例 ·find   path   -option   [   -print ]   [ -exec   -ok   command ]   {} \; find命令的参数 ...

  7. iOS 开发多线程篇—GCD的常见用法

    iOS开发多线程篇—GCD的常见用法 一.延迟执行 1.介绍 iOS常见的延时执行有2种方式 (1)调用NSObject的方法 [self performSelector:@selector(run) ...

  8. iOS开发多线程篇—GCD的常见用法

    iOS开发多线程篇—GCD的常见用法 一.延迟执行 1.介绍 iOS常见的延时执行有2种方式 (1)调用NSObject的方法 [self performSelector:@selector(run) ...

  9. [转]EasyUI——常见用法总结

    原文链接: EasyUI——常见用法总结 1. 使用 data-options 来初始化属性. data-options是jQuery Easyui 最近两个版本才加上的一个特殊属性.通过这个属性,我 ...

随机推荐

  1. 网页基础学习--网络结构和HTML(未完待续)

    一.网络常见基本结构: 1.B/S网络结构: Browser/Server:浏览器/服务器,这是现在最流行的网络模式.平常的上网:比如新浪网.凤凰网等.我的电脑(客户端)               ...

  2. 在线机器学习FTRL(Follow-the-regularized-Leader)算法介绍

    看到好文章,坚决转载!哈哈,学术目的~~ 最近几个同事在做推荐平台的项目,都问到怎么实现FTRL算法,要求协助帮忙实现FTRL的算法模块.今天也是有空,赶紧来做个整理.明天还要去上海参加天善智能组织的 ...

  3. Swift 3 点击屏幕任意位置隐藏键盘

    func hideKeyboardWhenTappedAround() { let tap: UITapGestureRecognizer = UITapGestureRecognizer(targe ...

  4. HTML字符实体(Character Entities),转义字符串(Escape Sequence) 转

    为什么要用转义字符串? HTML中<,>,&等有特殊含义(<,>,用于链接签,&用于转义),不能直接使用.这些符号是不显示在我们最终看到的网页里的,那如果我们希 ...

  5. 文本数据预处理:sklearn 中 CountVectorizer、TfidfTransformer 和 TfidfVectorizer

    文本数据预处理的第一步通常是进行分词,分词后会进行向量化的操作.在介绍向量化之前,我们先来了解下词袋模型. 1.词袋模型(Bag of words,简称 BoW ) 词袋模型假设我们不考虑文本中词与词 ...

  6. windows cmd 命令行 —— 进程与服务

    1. 进程查看与操作 tasklist tskill pid 2. 服务查看与操作 net start net stop

  7. HDU2037 今年暑假不AC

    解题思路:贪心问题,关键突破口是,先将节目的结束时间 从小到大排个序,然后依次判断后面一个节目的开始时间 是否大于或等于前一个符合条件的节目的结束时间.见代码: #include<cstdio& ...

  8. C语言共用体union

    union共用体说明: 当一个共用体被声明时, 编译程序自动地产生一个变量, 其长度为联合中最大的变量长度的整数倍. 比如union中有{int x; double x1; char name[10] ...

  9. Python tarfile模块解压报错 invalid mode ('wb') or filename

    问题原因 在使用tarfile模块解压一份Linux服务器上的打包文件时, 出现了错误提示: IOError: [Errno 22] invalid mode ('wb') or filename. ...

  10. elixir grpc 试用

    备注:  elixir  grpc 封装测试   1.  安装 a. 安装 protoc 参考相关文档,比较简单 b. 安装elixir grpc 插件 protoc-gen-elixir 同时配置环 ...