在Asp.Net Core中配置使用EFCore
本文以Sqlite数据库为例,介绍如何在基于 .Net Core 的应用程序中(比如:asp.net core)配置使用 EFCore 。主要内容包括:
以依赖注入或非依赖注入的方式使用配置EFCore相关信息
如何通过EFCore 对数据进行增删改查,包括使用Jion进行表之间的连接查询的用法。
一、添加依赖
asp.net core 应用程序项目建立好后,添加以下引用。
Microsoft.EntityFrameworkCore.Sqlite
Microsoft.EntityFrameworkCore.Tools
Microsoft.VisualStudio.Web.CodeGeneration.Design
二、建立一个数据库上下文类
采用非依赖注入方式。
public class SqliteDbContext : DbContext
{
private string ConnectString = "Data Source=SqliteDatabase.db";
//定义类与表的对应关系(即:ModeUser类与数据库中的tb_user表对应)
public DbSet<ModelUser> tb_user { set; get; }
//重写父类中的 OnConfiguring 方法。以便初始化相关配置信息。
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlite(ConnectString);
}
//重写父类中的 OnModelCreating 方法。此类中可指定主键、指定属性是否是必须的、指定属生长度,或设置数据表之间的关系等。(根据需要,可以不重写该方法)
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<ModelUser>().HasKey(x => x.Id);
modelBuilder.Entity<ModelUser>().Property("Nick").IsRequired().HasMaxLength(20);
}
}
2.使用依赖注入方式
改写数据库上下文类如下:
public class SqliteDbContext : DbContext
{
//使用构造函数,相关的options由框架依赖注入。
public SqliteDbContext(DbContextOptions<SqliteDbContext> options) : base(options)
{
}
//定义类与表的对应关系(即:ModeUser类与数据库中的tb_user表对应)
public DbSet<ModelUser> tb_user { set; get; }
//重写父类中的 OnModelCreating 方法。此类中可指定主键、指定属性是否是必须的、指定属生长度,或设置数据表之间的关系等。(根据需要,可以不重写该方法)
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<ModelUser>().HasKey(x => x.Id);
modelBuilder.Entity<ModelUser>().Property("Nick").IsRequired().HasMaxLength(20);
}
}
在 Startup.cs 文件中的 ConfigureServices 方法中注入系统的 DbContext 对象。
services.AddDbContext<SqliteDbContext>(options =>
{
options.UseSqlite(Configuration.GetConnectionString("SqliteConnStr"));
});
在appsettings.json文中指定字符串连接。
"ConnectionStrings": {
"SqliteConnStr": "Data Source=SqliteDatabase.db"
}
三、建立数据操作仓库类
public class DataUserRepository
{
private readonly SqliteDbContext _DbContext;
public DataUserRepository(SqliteDbContext DbContext)
{
_DbContext = DbContext;
}
/// <summary>
/// 根据Id查询用户信息
/// </summary>
/// <param name="P_Id"></param>
/// <returns></returns>
public async Task<ModelUser> GetOneByIdAsync(string P_Id)
{
return await _DbContext.tb_user.FindAsync(P_Id);
}
/// <summary>
/// 返回指定条件的所有用户
/// </summary>
/// <returns></returns>
public async Task<List<ModelUser>> GetAllAsync(Expression<Func<ModelUser, bool>> whereLambda)
{
return await _DbContext.tb_user.Where(whereLambda).ToListAsync();
}
/// <summary>
/// 向数据库表添加一个新的记录,如果该记录已经存在,返回-2。
/// </summary>
/// <param name="P_Entity"></param>
/// <returns></returns>
public async Task<int> AddNew(ModelUser P_Entity)
{
if (P_Entity == null) return -1;
bool IsExist = _DbContext.tb_user.Count(e => e.Id == P_Entity.Id) > 0;
if (IsExist)
{
return -2;
}
_DbContext.tb_user.Add(P_Entity);
return await _DbContext.SaveChangesAsync();
}
/// <summary>
/// 根据Id删除用户信息
/// </summary>
/// <param name="P_Id"></param>
/// <returns></returns>
public async Task<int> DelOneByIdAsync(string P_Id)
{
int actResult = 0;
if (!string.IsNullOrWhiteSpace(P_Id))
{
ModelUser user = await GetOneByIdAsync(P_Id);
if (user != null)
{
_DbContext.tb_user.Remove(user);
actResult = await _DbContext.SaveChangesAsync();
}
}
return actResult;
}
/// <summary>
/// 删除所有记录信息(直接使用SQL语句)
/// </summary>
/// <param name="P_Id"></param>
/// <returns></returns>
public async Task<int> DelAllDatasAsync()
{
int actResult = await _DbContext.Database.ExecuteSqlRawAsync($"DELETE FROM TB_USER WHERE Role<>'Admin'");
return actResult;
}
/// <summary>
/// 更改指定用户的密码
/// </summary>
/// <param name="P_Id"></param>
/// <param name="p_newPwd"></param>
/// <returns></returns>
public async Task<int> ChangePwd(string P_Id, string p_newPwd)
{
int actResult = 0;
if (!string.IsNullOrWhiteSpace(P_Id))
{
ModelUser user = await GetOneByIdAsync(P_Id);
if (user != null)
{
user.Pwd = p_newPwd;
_DbContext.Update(user);
actResult = await _DbContext.SaveChangesAsync();
}
}
return actResult;
}
}
上述数据操作类建好后,可以在Controller中使用。
其他内容
两个数据库连接查询(不需要建数据表时指定外键)
var scoreList = await _DbContext.tb_score.Join(_DbContext.tb_user, pet => pet.UserId, per => per.Id, (pet, per) => new
{
ProgramId=pet.ProgramId,
Score=pet.Score,
userRole = per.Role,
userUnit = per.Unit
}).Where(e => e.ProgramId.Equals(P_ProgramId)).ToListAsync();
此代码中pet代表 tb_score 表对象,per 代表 tb_user 表对象,两者通过 pet.UserId==per.Id 条件进行连接查询。
当然,如果在建表时已经指定了外键关系,则可通过 Include() 进行查询。
_DbContext.tb_score.Include(o=>o.tb_user).SingleOrDefault(e => e.Score=100);
2. 关于数据迁移。 通过控制台创建数据库,即使用本文开头引用的后两个程序包。
PM> get-help entityframeworkcore //可以先查看一下支持哪些命令
Cmdlet Description
Add-Migration Adds a new migration.
Drop-Database Drops the database.
Get-DbContext Gets information about a DbContext type.
Remove-Migration Removes the last migration.
Scaffold-DbContext Scaffolds a DbContext and entity types for a database.
Script-DbContext Generates a SQL script from the current DbContext.
Script-Migration Generates a SQL script from migrations.
Update-Database Updates the database to a specified migration.
PM> Add-Migration InitDatabase //生成数据迁移文件,其中‘InitDatabase’是为本次迁移的命名
...
PM> Update-Database //运行迁移文件,生成相应的数据库和表。
...