在上一节中,实现了CodeFirst快速入门。可是不少与数据库的细节还没法自定义。以及使用EF过程当中,须要注意的事项。html
在本节中,会涉及到如下sql
1个完整的链接字符串 IP:端口\实例名 数据库名组成并发
Nuget安装完EF会在*.config的entityFramework节点下添加,表示使用LocalDb数据库,实例名为v11.0。mvc
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework"> <parameters> <parameter value="v11.0" /> </parameters> </defaultConnectionFactory>
而数据库名,默认为类的全限定名。以下调用父类构造函数,表示数据库名为SaleDb。而不是命名空间+类名。app
public class SaleDb : DbContext { public SaleDb():base("SaleDb") { } }
固然,在这个构造函数里,能够完整的写上完整的链接字符串。框架
db.Entry(TEntity).State (附加Entity,并设置状态)ide
public enum EntityState { // 摘要: // The entity is not being tracked by the context. An entity is in this state // immediately after it has been created with the new operator or with one of // the System.Data.Entity.DbSet Create methods. Detached = 1, // // 摘要: // The entity is being tracked by the context and exists in the database, and // its property values have not changed from the values in the database. Unchanged = 2, // // 摘要: // The entity is being tracked by the context but does not yet exist in the // database. Added = 4, // // 摘要: // The entity is being tracked by the context and exists in the database, but // has been marked for deletion from the database the next time SaveChanges // is called. Deleted = 8, // // 摘要: // The entity is being tracked by the context and exists in the database, and // some or all of its property values have been modified. Modified = 16, }
延迟加载(lazy load)是(也称为懒加载),延迟加载机制是为了不一些无谓的性能开销而提出来的,所谓延迟加载就是当在真正须要数据的时候,才真正执行数据加载操做。能够简单理解为,只有在使用的时候,才会发出sql语句进行查询。
贪婪加载则是一次性把相关的表也加载进来。
在EF中,默认是支持延迟加载的。
db.Configuration.LazyLoadingEnabled = false; //设置禁用延迟加载
若是想单个贪婪加载某个表。则经过Include("表名")
db.Orders.Include("OrderItems"); //把OrderItems表一并加载进来
Virtual关键字
一般相关连的表做为Entity属性的时候,使用Virtual关键字修饰符。若是不加Virtual关键字,则关联的类只是一个普通的POCO类型。get,set方法为空实现。
使用Virtual关键字后,EF生成一个代理类来重写get和set方法。实现须要的功能。
EF做为一个框架,也不可能作到知足全部需求。EF提供了直接操做Ado.net方式。
有三个 API 支持:
执行sql 返回受影响函数。
public int ExecuteSqlCommand(string sql, params object[] parameters);
执行sql 返回查询结果并自动映射到指定类上。(不会被EF跟踪状态)
DbRawSqlQuery<TElement> SqlQuery<TElement>(string sql, params object[] parameters);
执行sql 返回查询结果并自动映射到指定类上。(被EF跟踪状态。DbSqlQuery继承自DbRawSqlQuery)
virtual DbSqlQuery<TEntity> SqlQuery(string sql, params object[] parameters);
当使用EF执行一个复杂的查询时候。咱们须要知道EF是否按照咱们所需执行。这时,就须要查看EF生成的语句。
DataAnnotation 特性由.NET 3.5中引进,给.NET中的类提供了一种添加验证的方式。同时在EF中,也是添加约束与个性化设置一种方式。
经常使用到如下特性。
public class Order { [Key] public int Id { get; set; } [StringLength(200)] public string Name { get; set; } public int UserId { get; set; } [ForeignKey("UserId")] public User User { get; set; } public virtual ICollection<OrderItem> OrderItems { get; set; } }
使用DataAnnotation(DA)很是方便,但有时咱们的POCO类不但愿受到EF的直接关联。或者DA不能知足需求。这时,咱们可使用FluentAPI方式。
protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity<AppInfo>().Property(o => o.Id).HasColumnName("AppId"); }
微软自家的东西关联老是那么方便。
在MVC5中,添加控制器的时候选择使用EF即自动生成这一切。
1.模型改变从新生成数据库,致使表数据丢失。
在使用CodeFirst中,当模型改变的时候,采用第一节中的Nuget中EF Migration API方式则不会清空数据。
2.是否使用存储过程,视图这些数据库技术。
当使用EF 这种ORM框架的时候,就应该轻数据库技术,重业务逻辑层。个人建议是万不得已不要使用存储过程,视图实际只是存储了SQL语句。
MVC5代码下载:MVCTest