第六节:框架搭建之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 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。
最新文章
- TypeScript 强类型 JavaScript – Rafy Web 框架选型
- 如何在ios中集成微信登录功能
- springBoot专题3---->;springBoot与多数据源的配置
- jquery 判断网络图片,或网络文件是否存在
- Java中常用的运算符
- The Simplified Project Management Process
- HDU 3308 线段树 最长连续上升子序列 单点更新 区间查询
- 【floyd存字典序路径】【HDU1385】【Minimum Transport Cost】
- drupal THEME主要文件
- SLB vs CLB
- H5基础浏览器兼容性
- MyEclipse10+Flash Builder4+BlazeDS+Tomcat7配置J2EE Web项目报错(一)
- 【Spark篇】---Spark调优之代码调优,数据本地化调优,内存调优,SparkShuffle调优,Executor的堆外内存调优
- VS Resharper正常代码显示红色处理
- python中常用函数整理
- JavaScript高级编程——Array数组迭代(every()、filter()、foreach()、map()、some(),归并(reduce() 和reduceRight() ))
- OWASP TOP10(2017)
- python第二十八课——编码小常识
- MVC插件
- WebClient请求帮助类
热门文章
- Django--session(登录用)
- Django组件--forms组件(注册用)
- git -分支管理(创建、推送、删除)
- Loj #2495. 「AHOI / HNOI2018」转盘
- BZOJ3711 Druzyny 最大值分治、线段树
- Player启动时提示 ";System.InvalidOperationException:无法加载计数器名称数据
- ST表
- Linux 学习 (九) 网络基础
- 怼天怼地怼空气的Linus喜欢怎样的工作方式?
- AJAX初识(原生JS版AJAX和Jquery版AJAX)