ASP.NET Core模块化前后端分离快速开发框架介绍之3、数据访问模块介绍

栏目: ASP.NET · 发布时间: 5年前

内容简介:地址:账户:admin密码:admin

地址: http://129.211.40.240:6220

账户:admin

密码:admin

前端框架演示地址(临时)

地址: http://progqx5cu.bkt.clouddn.com/skins/index.html#/

账户:admin

密码:admin

目录

1、开篇

2、快速创建一个业务模块

3、数据访问模块介绍

简介

NetModular 的数据访问模块是基于 Dapper 扩展的轻量级的ORM,它本身是完全独立的,可以在任何项目中直接使用。在 NetModular 中也提供了扩展,能够完美的与模块化集成在一起。

支持的功能

  • 支持SqlServer、 MySqlSQLite 数据库
  • 基础的CRUD方法
  • 批量添加、删除、修改
  • 修改指定列
  • Lamdba表达式支持
  • 多表连接查询
  • 分页查询
  • 分组查询
  • 仓储模式
  • 工作单元
  • 自定义表名、列名
  • 支持同步/异步方法

使用方法

NetModular 本身已经做好了集成,所以业务模块中,可以直接写代码,不用考虑注入的问题,如果想要了解它的集成逻辑的,可以查看 Data.AspNetCore

ASP.NET Core模块化前后端分离快速开发框架介绍之3、数据访问模块介绍

Node:数据库上下文、仓储和工作单元的注入方式采用的是 Scoped

1、添加数据库上下文

数据库上下文需要继承 DbContext

public class MallDbContext : DbContext
{
    public MallDbContext(IDbContextOptions options) : base(options)
    {
    }
}

2、创建实体

实体需要继承 IEntity 接口,在 NetModular 中,已经提供了几个通用的实体基类,并且内部已经实现了对应的功能,比如 EntityBase

public class EntityBase<TKey> : Entity<TKey>
{
    /// <summary>
    /// 创建时间
    /// </summary>
    public DateTime CreatedTime { get; set; } = DateTime.Now;

    /// <summary>
    /// 创建人
    /// </summary>
    public Guid CreatedBy { get; set; }

    /// <summary>
    /// 修改时间
    /// </summary>
    public DateTime ModifiedTime { get; set; } = DateTime.Now;

    /// <summary>
    /// 修改人
    /// </summary>
    public Guid ModifiedBy { get; set; }

    /// <summary>
    /// 创建人名称
    /// </summary>
    [Ignore]
    public string Creator { get; set; }

    /// <summary>
    /// 修改人
    /// </summary>
    [Ignore]
    public string Modifier { get; set; }
}

可以看到 EntityBase 已经包含了 CreatedTime , CreatedBy , ModifiedTime , ModifiedBy 这四个实体属性,通过实体继承了 EntityBase ,那么该实体也包含了这个属性,同时 NetModular 内部已经实现了在添加,修改时,自动设置对应的创建人和修改人编号,所以你不需要你去考虑这些事情了。

另外还有包含软删除功能的 EntityWithSoftDelete 以及包含上面两个实体功能的 EntityBaseWithSoftDelete 两个实体,这些都已经封装好了,可以直接用。

Node:上面的三个实体基类都会继承自 Entity ,该实体包含了一个主键 Id ,主键类型支持Guid(默认)、Int、Long三种类型。

可以通过Table特性,设置实体对应的表名称

以下是一个产品的实体示例:

[Table("Product")]
public partial class ProductEntity : EntityBase
{
    /// <summary>
    /// 标题
    /// </summary>
    public string Title { get; set; }

    /// <summary>
    /// 价格
    /// </summary>
    public decimal Price { get; set; }

    /// <summary>
    /// 库存
    /// </summary>
    public int Store { get; set; }

    /// <summary>
    /// 状态
    /// </summary>
    public ProductStatus Status { get; set; }
}

实体扩展类:

Node:实体扩展类中的属性,必须添加 Ignore 特性,否则属性会被当成表的列处理。

public partial class ProductEntity
{
    /// <summary>
    /// sku列表
    /// </summary>
    [Ignore]
    public List<Guid> Skus { get; set; }
}

3、添加仓储接口

仓储接口必须继承 IRepository<> 接口

/// <summary>
/// 产品仓储接口
/// </summary>
public interface IProductRepository : IRepository<ProductEntity>
{
    /// <summary>
    /// 查询
    /// </summary>
    /// <param name="model"></param>
    /// <returns></returns>
    Task<IList<ProductEntity>> Query(ProductQueryModel model);
}

4、添加查询模型

查询模型包含查询条件,需要继承 QueryModel 类,该类包含了分页相关的信息

public class ProductQueryModel : QueryModel
{
    public string Title { get; set; }
}

5、添加仓储实现

仓储实现需要继承抽象仓储 RepositoryAbstract<> ,不同数据库的仓储实现,需要放到不同的目录中。因为不同的数据库难免会有一些查询,所以我们采用先实现一种数据库的实现,然后其它数据实现直接继承它,对于有查询的方法,采用覆写的方式实现。

public class ProductRepository : RepositoryAbstract<ProductEntity>, IProductRepository
{
    public ProductRepository(IDbContext context) : base(context)
    {
    }

    public async Task<IList<ProductEntity>> Query(ProductQueryModel model)
    {
        //分页
        var paging = model.Paging();

        var query = Db.Find();
        query.WhereIf(model.Title.NotNull(), m => m.Title.Contains(model.Title));

        //设置默认排序
        if (!paging.OrderBy.Any())
        {
            query.OrderByDescending(m => m.Id);
        }

        var list = await query.PaginationAsync(paging);
        model.TotalCount = paging.TotalCount;
        return list;
    }
}

上面的例子是一个最简单的分页查询,到此数据访问的代码就写完了,剩下的就是在服务层调用就行了。

其它用法说明

1、CRUD

基础的CRUD在 RepositoryAbstract 中已经实现了,所以可以直接在服务中调用

新增

_repository.AddAsync(entity);

批量新增

_repository.AddAsync(entities);

删除

_repository.DeleteAsync(id);

软删除

_repository.SoftDeleteAsync(id);

修改

_repository.UpdateAsync(entity);

获取

_repository.GetAsync(id);

获取所有

_repository.GetAllAsync()

是否存在

_repository.ExistsAsync(m => m.Title.Contains("test"))

批量修改

/// <summary>
/// 批量修改状态
/// </summary>
/// <param name="ids"></param>
/// <param name="status"></param>
/// <returns></returns>
public Task<bool> UpdateStatus(List<Guid> ids, ProductStatus status)
{
    return Db.Find(m => ids.Contains(m.Id)).UpdateAsync(m => new ProductEntity { Status = status });
}

批量删除

/// <summary>
/// 批量删除
/// </summary>
/// <param name="title"></param>
/// <returns></returns>
public Task<bool> Delete(string title)
{
    return Db.Find(m => m.Title.Contains(title)).DeleteAsync();
}

表连接查询

public async Task<IList<ProductEntity>> Query(ProductQueryModel model)
{
    //分页
    var paging = model.Paging();

    var query = Db.Find();
    query.WhereIf(model.Title.NotNull(), m => m.Title.Contains(model.Title));

    //设置默认排序
    if (!paging.OrderBy.Any())
    {
        query.OrderByDescending(m => m.Id);
    }

    var list = await query.LeftJoin<AccountEntity>((x, y) => x.CreatedBy == y.Id)
        .Select((x, y) => new { x, Creator = y.Name })
        .PaginationAsync(paging);

    model.TotalCount = paging.TotalCount;
    return list;
}

分组查询

Db.Find().GroupBy(m => new { m.Status }).Select(m => new { m.Key.Status, Count = m.Count() });

工作单元

工作单元在服务中注入使用

private readonly IUnitOfWork _uow;
public ArticleService(IUnitOfWork<MalDbContext> uow)
{
    _uow = uow;
}

然后通过 BeginTransaction 方法开启事务, Commit 方法提交事务, Rollback 方法回滚事务

_uow.BeginTransaction();
var result = await _accountRepository.AddAsync(account);
if (result)
{
    if (model.Roles != null && model.Roles.Any())
    {
        var accountRoleList = model.Roles.Select(m => new AccountRoleEntity { AccountId = account.Id, RoleId = m }).ToList();
        if (await _accountRoleRepository.AddAsync(accountRoleList))
        {
            _uow.Commit();
            return ResultModel.Success();
        }
    }
    else
    {
        _uow.Commit();
        return ResultModel.Success();
    }
}

好了,数据库访问的用法大致就是这样~


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

浅薄

浅薄

[美] 尼古拉斯·卡尔 / 刘纯毅 / 中信出版社 / 2010-12 / 42.00元

《浅薄:互联网如何毒化了我们的大脑》在我们跟计算机越来越密不可分的过程中,我们越来越多的人生体验通过电脑屏幕上闪烁摇曳、虚无缥缈的符号完成,最大的危险就是我们即将开始丧失我们的人性,牺牲人之所以区别于机器的本质属性。——尼古拉斯•卡尔“谷歌在把我们变傻吗?”当尼古拉斯•卡尔在发表于《大西洋月刊》上赫赫有名的那篇封面文章中提出这个问题的时候,他就开启了人们热切渴望的期盼源泉,让人急于弄清楚互联网是在......一起来看看 《浅薄》 这本书的介绍吧!

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具