转载

ASP.NET5+EntityFramework7开发实践(一)

1.创建项目

创建“空白解决方案”,名为 GiveCase

在解决方案里,添加ASP.NET5 Empty模板项目,名为 GiveCase.Web

2.实体类

实体基类:

1     /// <summary>  2     /// 实体 抽象基类  3     /// </summary>  4     /// <typeparam name="TKey">主键类型</typeparam>  5     public abstract class EntityBase<TKey>  6     {  7         /// <summary>  8         /// 主键  9         /// </summary> 10         public TKey Id { get; set; } 11     }

角色实体类

1     /// <summary>  2     /// 角色 实体类  3     /// </summary>  4     public class Role:EntityBase<int>  5     {  6         /// <summary>  7         /// 角色名  8         /// </summary>  9         public string Name { get; set; } 10  11         /// <summary> 12         /// 角色描述 13         /// </summary> 14         public string Description { get; set; } 15  16         /// <summary> 17         /// 用户集合 导航属性 18         /// </summary> 19         public virtual ICollection<User> Users { get; set; } 20     }

用户实体类:

1     /// <summary>  2     /// 用户 实体类  3     /// </summary>  4     public class User : EntityBase<int>  5     {  6         /// <summary>  7         /// 用户名  8         /// </summary>  9         public string Name { get; set; } 10  11         /// <summary> 12         /// 密码 13         /// </summary> 14         public string Password { get; set; } 15  16         /// <summary> 17         /// 角色Id 外键 18         /// </summary> 19         public int RoleId { get; set; } 20  21         /// <summary> 22         /// 角色 导航属性 23         /// </summary> 24         public virtual Role Role { get; set; } 25     }

3.EF安装

打开project.json,在 "dependencies": {}中,添加:

"EntityFramework.Commands": "7.0.0-beta8",     "EntityFramework.SqlServer": "7.0.0-beta8"

在"commands": {}中,添加:

"ef": "EntityFramework.Commands"

注: 如果你不需要手动迁移数据库,可以不要用安装 EntityFramework.Commands及配置其commands。

4.数据库上下文

数据库上下文类:

1     /// <summary>  2     /// 数据库上下文类  3     /// </summary>  4     public class EFContext : DbContext  5     {  6         public DbSet<Role> Roles { get; set; }  7         public DbSet<User> Users { get; set; }  8   9         protected override void OnModelCreating(ModelBuilder modelBuilder) 10         { 11             #region 角色属性 12             modelBuilder.Entity<Role>().Property(r => r.Name).IsRequired(); 13             modelBuilder.Entity<Role>().Property(r => r.Description).HasMaxLength(300); 14             #endregion 15  16             #region 用户属性 17             modelBuilder.Entity<User>().Property(u => u.Name).IsRequired(); 18             modelBuilder.Entity<User>().Property(u => u.Password).IsRequired(); 19             #endregion 20  21             #region 配置关系 22             modelBuilder.Entity<Role>().HasMany(r => r.Users).WithOne(u => u.Role) 23                 .ForeignKey(u => u.RoleId).WillCascadeOnDelete(); 24             #endregion 25         } 26     }

注: 配置属性及关系,这里采用是Fluent API方式,你可以在实体类代码中采用Data Annotations特性标注方式。

5.数据库连接字符串

添加config.json,其代码:

{   "Data": {     "Connection": {       "ConnectionString": "Server=.;Database=GiveCase;User ID=sa;Password=123456;"     }   } }

5.配置文件读取

修改Startup.cs中的方法:

1       public IConfigurationRoot Configuration { get; set; }  2   3         public Startup(IApplicationEnvironment appEnv)  4         {  5             var builder = new ConfigurationBuilder()  6                 .SetBasePath(appEnv.ApplicationBasePath)  7                 .AddJsonFile("config.json");  8   9             Configuration = builder.Build(); 10         } 11           12         public void ConfigureServices(IServiceCollection services) 13         { 14             services.AddEntityFramework().AddSqlServer() 15                 .AddDbContext<EFContext>(options => options 16                 .UseSqlServer(Configuration["Data:Connection:ConnectionString"])); 17         }

6.手动迁移数据库

在VS中的“程序包管理器控制台”(在dos也行)下,进入到项目根目录。

执行: dnx ef migrations add FristMigration

命令执行成功后,项目结构就填加了Migrations文件夹,里面会有ModelSnapshot文件。

此时并没有创建数据库,再执行: dnx ef database update

这样两步骤(添加数据库迁移,更新到数据库)就完成数据库创建。

7.控制器代码生成

打开project.json ,在"dependencies": {}中,添加:

"Microsoft.Framework.CodeGeneration": "1.0.0-beta8",     "Microsoft.Framework.CodeGenerators.Mvc": "1.0.0-beta8",

在"commands": {}中,添加:

"gen": "Microsoft.Framework.CodeGeneration"

在VS中的“程序包管理器控制台”(在dos也行)下,进入到项目根目录。

我们添加Home控制器,执行: dnx gen controller -name HomeController

此时项目结构就添加Controllers和Views文件夹等,也添加了Microsoft.AspNet.Mvc程序集。

如何生成T4(GRUD)模板的控制器?

添加Role控制器,执行: dnx gen controller -name RoleController -m Role -dc EFContext

这样控制器代码,增删改查方法有了,相应的视图也生成了。

8.仓库模式

我们已经生成的代码,最好封装一下持久化操作。先不用泛型封装,添加接口:

1     public interface IRoleRepository : IDisposable  2     {  3         //IEnumerable和IQueryable  4         //二者在EF都会延迟加载,不同的是:  5         //IEnumerable是数据加载到内存,刷选在内存中的数据上执行  6         //IQueryable是查询和刷选在数据源中执行  7   8         //TODO:复杂条件查询和异步方法  9  10         //IQueryable<Role> GetRoles(); 11         IEnumerable<Role> GetRoles(); 12         Role GetRole(int? id); 13         void Create(Role role); 14         void Update(Role role); 15         void Delete(int? id); 16     }

其实现代码:

1     public class RoleRepository : IRoleRepository  2     {  3         private EFContext db;  4         public RoleRepository(EFContext _db)  5         {  6             db = _db;  7         }  8   9         public IEnumerable<Role> GetRoles() 10         { 11             return db.Roles.ToList(); 12         } 13  14         public Role GetRole(int? id) 15         { 16             return db.Roles.Single(m => m.Id == id); 17         } 18  19         public void Create(Role role) 20         { 21             db.Roles.Add(role); 22             db.SaveChanges(); 23         } 24  25         public void Delete(int? id) 26         { 27             db.Roles.Remove(db.Roles.Single(m => m.Id == id)); 28             db.SaveChanges(); 29         } 30  31         public void Update(Role role) 32         { 33             db.Update(role); 34             db.SaveChanges(); 35         } 36  37         //public void Save() 38         //{ 39         //    db.SaveChanges(); 40         //} 41  42         #region 释放资源 43         private bool disposed = false; 44         protected virtual void Dispose(bool disposing) 45         { 46             if (!disposed) 47             { 48                 if (disposing) { db.Dispose(); } 49             } 50             disposed = true; 51         } 52         public void Dispose() 53         { 54             Dispose(true); 55             System.GC.SuppressFinalize(this); 56         } 57         #endregion 58     }

9.工作单元模式

工作单元的目的,保证多个数据仓库一起操作保持一致。先创建接口:

1     public interface IUnitOfWork 2     { 3         //TODO:事务,异步 4         void SaveChanges(); 5     }

其实现:

1     public class UnitOfWork : DbContext, IUnitOfWork 2     { 3         public new void SaveChanges() 4         { 5             base.SaveChanges(); 6         } 7     }

10.仓库基类封装

基类封装:

1     public class BaseRepository  2     {  3         protected IUnitOfWork UnitOfWork { get; set; }  4   5         protected EFContext db  6         {  7             get { return (EFContext)UnitOfWork; }  8         }  9  10         public BaseRepository(IUnitOfWork _unitOfWork) 11         { 12             if (_unitOfWork == null) 13             { 14                 throw new ArgumentNullException("_unitOfWork"); 15             } 16  17             UnitOfWork = _unitOfWork; 18         } 19  20         public void Save() 21         { 22             db.SaveChanges(); 23         } 24  25         protected virtual DbSet<TEntity> GetDbSet<TEntity>() where TEntity : class 26         { 27             return db.Set<TEntity>(); 28         } 29  30         protected virtual void SetEntityState(object entity, EntityState entityState) 31         { 32             db.Entry(entity).State = entityState; 33         } 34     }

11.小结

篇幅有些长了,下一章再说控制器基类封装,依赖注入,界面展示……

正文到此结束
Loading...