EF有3种设计模式:
Database-First
Model-First
Code-First
如果不用对数据库的设计进行严格控制的话,对于需要根据需求业务变动进行快速开发的项目来说,Code-First无疑是最合适
而且Code-First的实体类是POCOs,不会包含其它多余的属性和方法,可以直接拿来当做MVC模型使用
可以直接执行Sql语句
一、EF的使用建议
但我觉得,关于Code-First提倡一些东西,可以不用
比如通过导航属性实现的实体外键关系,原本,数据库外键这种东西我不建议使用,在企业的数据库开发中也很少使用。因为它会增加数据库表的维护难度:
比如A表和B表建立了的1对N的外键关系
1、会占用数据库的存储空间
2、在相应表的增删改时,会额外消耗数据库服务器的运算资源
3、会减慢数据增删改的速度
4、如果A表一条数据出现了错误,我要删除,那我必须删除关连B表所有的数据;更新也同样麻烦。虽然数据库有级联删除和更新,但如果是误操作那就完蛋了。并且如果我只想更新A表的时候,数据库后台自动帮我更新了B表,这感觉像是不可预知,因此不可接受。
5、如果我要在A表独立建立一条数据,那么BID字段我必须参考B表,没有还要先创建
基于上述几种原因,造成数据的维护加大,也消耗了服务器系统的性能。同时在EF中,如使用导航属性,将会产生一些多余的属性,实体类使用起来更复杂和难道理解,也违背了POCOs原则
当然,如果采用Database-First,原来的数据模型就有外键关系,不好修改,那我建议删除掉EF默认级联关系:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Appointment>().HasRequired(a => a.Sponsor).WithMany(u => u.SpoAppointments).WillCascadeOnDelete(false);
modelBuilder.Entity<Appointment>().HasRequired(a => a.Recipient).WithMany(u => u.RecAppointments).WillCascadeOnDelete(false);
}
二、EF的使用
EF的使用跟Linq to Sql很相似,教程网上很多,这里我直接引述
创建步骤:
http://www.cnblogs.com/Wayou/archive/2012/09/20/EF_CodeFirst.html
数据库迁移:
http://www.cnblogs.com/libingql/p/3330880.html
常用的两个数据库迁移命令:
Enable-Migrations -EnableAutomaticMigrations
加-Force表示强制执行,但前提你必须确认实体类修改无误Update-Database -Verbose
三、EF使用技巧
除了前面说的移除默认的级联关系,我们在使用EF时发现自动生成的表默认加上了s或es,并且在调试时模型验证出错时没有提示是哪个属性出错了,这些可以通过以下方法来解决:
/// <summary>
/// 移除EF映射默认给表名添加“s“或者“es”
/// </summary>
/// <param name="modelBuilder"></param>
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Entity<User>().HasKey(o => o.Id);
base.OnModelCreating(modelBuilder);
}
/// <summary>
/// 模型验证出错时抛出异常
/// </summary>
/// <returns></returns>
public override int SaveChanges()
{
try
{
return base.SaveChanges();
}
catch (DbEntityValidationException ex)
{
var errMsg = ex.EntityValidationErrors.SelectMany(o => o.ValidationErrors).Select(o => o.ErrorMessage);
var fullErrMsg = ex.Message + ":" + string.Join(";", errMsg);
throw new DbEntityValidationException(fullErrMsg, ex.EntityValidationErrors);
}
}