玩转ASP.NET 5:初始化数据库
1.初始化数据库
- 1.2目录
这不是专述模式/架构设计的帖子,架构搭建以讲解文章为目的,先不过多分层。
截这个图也是便于你对应下面找代码文件路径!
- 1.2代码
先控制台应用程序来演示。(比较蛋疼,MS针对ASP.NET 5测试框架在beta1版中,可用XUnit.KRunner。beta2中我也不知道用那个。)
不管你用不用EF?传统做法先设计数据库,但写代码面向对象开发时还是要设计实体(模型),为了方便映射实体的属性和数据库字段是一一对应(也可以通过Fluent API配置,实体属性设计和字段不对应)。实体可以当作业务对象,视图模型,传输对象。但根据需要这些对象或模型属性不一定和数据库字段一致,可以另外定义。
我们先设计一个实体基类(还是那句话,仅供讲解,代码不全或不严谨,理解万岁啦!):
using System.ComponentModel.DataAnnotations; namespace BlogASPNET5.Entity.Bases { /// <summary> /// 实体基类 /// </summary> /// <typeparam name="T">主键类型</typeparam> public class EntityBase<T> { [Key] public T Id { get; set; } //记录创建时间 //是否删除 //行版本 } }
注:EF对于主键类型为整型和Guid类型,其属性为Id或类名+Id(不分大小写),可以不用标注Key;整型自增,便于阅读;Guid,便于数据合并;也可以字符串。所以这里用到泛型,继承时再决定什么类型。
下面再定义Account相关的角色实体:
using BlogASPNET5.Entity.Bases; using System.Collections.Generic; namespace BlogASPNET5.Entity.Accounts { /// <summary> /// 角色实体 /// </summary> public class Role :EntityBase<int> { public string Name { get; set; } public string Description { get; set; } /// <summary> /// 导航属性 (后面演示Redis时,不要导航属性) /// </summary> public ICollection<User> Users { get; set; } } }
Account相关的用户实体:
using BlogASPNET5.Entity.Bases; namespace BlogASPNET5.Entity.Accounts { public class User : EntityBase<int> { public string Name { get; set; } public string Password { get; set; } public Gender Gender { get; set; } /// <summary> /// 角色Id 外键 /// </summary> public int RoleId { get; set; } /// <summary> /// 导航属性 /// </summary> public Role Role { get; set; } } /// <summary> /// 性别 枚举类型 /// </summary> public enum Gender { man, woman } }
注:EF7又不支持复杂类型(其实通过继承即可),但枚举类型支持保留;后面使用Redis,导航属性就没用了。
既然要用EF来创建数据库及初始化数据,需要EF操作上下文类:
using BlogASPNET5.Entity.Accounts; using Microsoft.Data.Entity; using Microsoft.Data.Entity.Metadata; namespace BlogASPNET5.Repository.Contexts { public class EFContext :DbContext { public DbSet<Role> Roles { get; set; } public DbSet<User> Users { get; set; } protected override void OnConfiguring(DbContextOptions options) { options.UseSqlServer("Server=.;Database=TestDB;UID=sa;PWD=123456;"); } protected override void OnModelCreating(ModelBuilder modelBuilder) { //多对一关系及指定外键 modelBuilder.Entity<User>().ManyToOne(r => r.Role, u => u.Users).ForeignKey(f => f.RoleId); } } }
定义初始化数据库方法:
using BlogASPNET5.Entity.Accounts; using BlogASPNET5.Repository.Contexts; using System.Linq; namespace BlogASPNET5.Repository.Migrations { public static class SampleData { static EFContext db = new EFContext(); public static void SetData() { db.Database.EnsureDeleted(); db.Database.EnsureCreated(); db.Add( new Role { Name = "manage", Description = "管理员" }, new Role { Name = "member", Description = "会员" }); db.SaveChanges(); //嘛蛋,CoreCLR没随机函数,循环啦 for (int i = 1; i <= 1000; i++) { db.Add( new User { Name = "admin" + i, Password = "abc" + i, Gender = Gender.man, Role = db.Roles.Single(r => r.Name == "manage") }); db.SaveChanges(); } for (int i = 1; i <= 1000; i++) { db.Add( new User { Name = "member" + i, Password = "efg" + i, Gender = Gender.woman, Role = db.Roles.Single(r => r.Name == "member") }); db.SaveChanges(); } } } }
- 1.3调用
在控制台程序调用:
using BlogASPNET5.Repository.Contexts; using BlogASPNET5.Repository.Migrations; using System; namespace BlogASPNET5.ConsoleApp { public class Program { public void Main(string[] args) { //初始化数据,创建完了注释掉 SampleData.SetData(); Console.WriteLine("set data OK!"); Console.ReadLine(); using (var db = new EFContext()) { var lists = db.Users; foreach (var item in lists) { Console.WriteLine(item.Name); } } Console.ReadLine(); } } }
结果就不截图了。 EF7 beta2又一个改进:创建出来的表,不再有MigrationHistory(看着不爽)这个表了。
2.小结
本篇先初始化数据库,下一章数据操作封装及查询分页。
打个“小广告 ”!欢迎志同道合的园友,加入QQ群:290576772(加时注明博客园)
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。