一. 前言

  沉寂了约一个月的时间,今天用一篇简单的文章重新回归博客,主要来探讨一下Fluent Api模式在实际项目中的使用流程。
1. Fluent API属于EF CodeFirst模式的一种,EF还有一种模式是DataAnnotations,两种模式各有千秋吧,前面的EF系列已经详细介绍过他们的使用了,本节主要介绍 Fluent API模式在实际框架中的使用流程.
本节需要用到的技术有:

  ①:EF的三种模式(四) 之 原生正宗的 CodeFirst模式的默认约定
  ②:EF的CodeFirst模式通过DataAnnotations修改默认协定
  ③:EF的CodeFirst模式通过Fluent API修改默认协定
  ④:EF的CodeFirst模式的四种初始化策略和通过Migration进行数据的迁移

2. 框架模式
  这里不采用传统的三层架构(DAL、BLL),而是使用:Ypf.DTO、Ypf.Service、Ypf.IService、Ypf.Utils、Ypf.Web 这种划分模式,本节为了方便测试,仅仅使用 Ypf.Service 和 Ypf.Test(控制台)两个框架进行测试。

3. 业务模拟
  ①. 用户基本信息和角色基本信息,不做关联
  ②. 用户信息增加了或者删除
  ③. 角色信息删除了或者增加

二. 使用步骤

1.  新建【Ypf.Service】类库和【Ypf.Test】控制台项目,并分别通过Nuget安装EF程序集。

2. 在【Ypf.Service】类库中新建“UserInfor”、“RoleInfor”实体类,“UserInforConfig”、“RoleInforConfig”实体类对应的隔离出来的表的配置文件。

PS:这里为了方便管理,一张表对应一个EF的配置类文件,比全部直接写在 OnModelCreating 方法中更清晰。

分享实体类代码:

     /// <summary>
/// 用户表
/// </summary>
public class UserInfor
{
public string id { get; set; }
public string userName { get; set; }
public int userAge { get; set; }
}
/// <summary>
/// 角色信息
/// </summary>
public class RoleInfor
{
public string id { get; set; }
public string roleName { get; set; }
public int roleAge { get; set; }
}

分享表配置文件代码:

     /// <summary>
/// UserInfor实体对应表的配置
/// </summary>
class UserInforConfig :EntityTypeConfiguration<UserInfor>
{
public UserInforConfig()
{
this.ToTable("T_UserInfor");
this.HasKey<string>(u => u.id).Property(u => u.id).HasColumnType("varchar").HasMaxLength();
this.Property(u => u.userName).HasColumnType("varchar").HasMaxLength();
this.Property(u => u.userAge).HasColumnType("int").IsRequired();
}
}
/// <summary>
/// RoleInfor实体对应表的配置
/// </summary>
class RoleInforConfig : EntityTypeConfiguration<RoleInfor>
{
public RoleInforConfig()
{
this.ToTable("T_RoleInfor");
this.HasKey<string>(u => u.id).Property(u => u.id).HasColumnType("varchar").HasMaxLength();
this.Property(u => u.roleName).HasColumnType("varchar").HasMaxLength();
this.Property(u => u.roleAge).HasColumnType("int").IsRequired();
}
}

3. 在【Ypf.Service】类库中新建EF上下文 “YpfContext”类,使用EF的默认初始化策略(DB不存在则创建,实体不对应则报错) ,然后override OnModelCreating方法,并通过反射一次性加载EF的所有Fluent Api配置,最后声明要映射的实体。

 分享EF上下文的代码

  public class YpfContext:DbContext
{
/// <summary>
/// 继承父类构造函数,ypfConnectionString代表配置文件中连接字符串的名字
/// </summary>
public YpfContext():base("name=ypfConnectionString")
{
} /// <summary>
/// OnModelCreating方法重写,FluentAPI对表的配置都是在该方法中,但是当表数量多的话
/// 该方法内部就会显得特别乱,所以我们这里采用分离的方式,一张表对应一个配置文件类,
/// 最后全部注册到该方法中即可
/// </summary>
/// <param name="modelBuilder"></param>
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder); //1. 分开注册
//modelBuilder.Configurations.Add(new UserInforConfig());
//modelBuilder.Configurations.Add(new RoleInforConfig()); //2. 一次性加载所有Fluent API的配置
modelBuilder.Configurations.AddFromAssembly(Assembly.GetExecutingAssembly());
} public DbSet<UserInfor> UserInfor { get; set; }
public DbSet<RoleInfor> RoleInfor { get; set; }
}

4. 给【Ypf.Test】配置数据库连接字符串,并且进行一个简单的数据库查询操作,会发现在SQLServer默认目录生成一个名为“FrameFluentApiDB”的数据库,且表、字段对应均正确。

 分享数据库连接字符串代码:

  <connectionStrings>
<add name="ypfConnectionString" connectionString="Data Source=localhost;Initial Catalog=FrameFluentApiDB;User ID=sa;Password=123456" providerName="System.Data.SqlClient" />
</connectionStrings>

分享简单的数据库查询代码:

  class Program
{
static void Main(string[] args)
{
using (YpfContext db=new YpfContext())
{
var list = db.UserInfor.ToList(); Console.WriteLine("创建成功");
Console.ReadKey();
}
}
}

 运行后生成的数据库:

5. 给UserInfor实体增加一个“userSex”属性,并在UserInforConfig文件中对该属性进行配置,如下图,再次运行代码,报错,提示上下文发生改变,请走数据迁移。

修改后代码:

报错提示:

PS:配置数据迁移策略固然可以解决该问题,但我们这里用一种比较笨的方法,关闭数据库初始化策略,然后手动配置代码和修改数据库字段进行对应即可。

 分享关闭数据库初始化策略的代码:

手动修改数据库和代码实体中的属性对应后重新运行代码,运行成功。

!

  • 作       者 : Yaopengfei(姚鹏飞)
  • 博客地址 : http://www.cnblogs.com/yaopengfei/
  • 声     明1 : 本人才疏学浅,用郭德纲的话说“我是一个小学生”,如有错误,欢迎讨论,请勿谩骂^_^。
  • 声     明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。
 

最新文章

  1. TypeScript 强类型 JavaScript – Rafy Web 框架选型
  2. 如何在ios中集成微信登录功能
  3. springBoot专题3----&gt;springBoot与多数据源的配置
  4. jquery 判断网络图片,或网络文件是否存在
  5. Java中常用的运算符
  6. The Simplified Project Management Process
  7. HDU 3308 线段树 最长连续上升子序列 单点更新 区间查询
  8. 【floyd存字典序路径】【HDU1385】【Minimum Transport Cost】
  9. drupal THEME主要文件
  10. SLB vs CLB
  11. H5基础浏览器兼容性
  12. MyEclipse10+Flash Builder4+BlazeDS+Tomcat7配置J2EE Web项目报错(一)
  13. 【Spark篇】---Spark调优之代码调优,数据本地化调优,内存调优,SparkShuffle调优,Executor的堆外内存调优
  14. VS Resharper正常代码显示红色处理
  15. python中常用函数整理
  16. JavaScript高级编程——Array数组迭代(every()、filter()、foreach()、map()、some(),归并(reduce() 和reduceRight() ))
  17. OWASP TOP10(2017)
  18. python第二十八课——编码小常识
  19. MVC插件
  20. WebClient请求帮助类

热门文章

  1. Django--session(登录用)
  2. Django组件--forms组件(注册用)
  3. git -分支管理(创建、推送、删除)
  4. Loj #2495. 「AHOI / HNOI2018」转盘
  5. BZOJ3711 Druzyny 最大值分治、线段树
  6. Player启动时提示 &quot;System.InvalidOperationException:无法加载计数器名称数据
  7. ST表
  8. Linux 学习 (九) 网络基础
  9. 怼天怼地怼空气的Linus喜欢怎样的工作方式?
  10. AJAX初识(原生JS版AJAX和Jquery版AJAX)