ASP.NET Core模塊化先後端分離快速開發框架介紹之三、數據訪問模塊介紹

源碼

GitHub:https://github.com/iamoldli/NetModularhtml

演示地址

地址:https://nm.iamoldli.com
帳戶:admin
密碼:admin前端

前端框架演示地址(臨時)

地址:http://nm.demo.iamoldli.com/index.html
帳戶:admin
密碼:admingit

目錄

一、開篇
二、快速建立一個業務模塊
三、數據訪問模塊介紹
四、模塊化實現思路github

簡介

NetModular 的數據訪問模塊是基於 Dapper 擴展的輕量級的ORM,它自己是徹底獨立的,能夠在任何項目中直接使用。在NetModular中也提供了擴展,可以完美的與模塊化集成在一塊兒。數據庫

支持的功能

  • [x] 支持SqlServer、MySql、SQLite數據庫
  • [x] 基礎的CRUD方法
  • [x] 批量添加、刪除、修改
  • [x] 修改指定列
  • [x] Lamdba表達式支持
  • [x] 多表鏈接查詢
  • [x] 分頁查詢
  • [x] 分組查詢
  • [x] 倉儲模式
  • [x] 工做單元
  • [x] 自定義表名、列名
  • [x] 支持同步/異步方法

使用方法

NetModular 自己已經作好了集成,因此業務模塊中,能夠直接寫代碼,不用考慮注入的問題,若是想要了解它的集成邏輯的,能夠查看Data.AspNetCore前端框架

Data.AspNetCore

Node: 數據庫上下文、倉儲和工做單元的注入方式採用的是Scopedapp

一、添加數據庫上下文

數據庫上下文須要繼承DbContext框架

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

二、建立實體

實體須要繼承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內部已經實現了在添加,修改時,自動設置對應的建立人和修改人編號,因此你不須要你去考慮這些事情了。async

另外還有包含軟刪除功能的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; }
}

三、添加倉儲接口

倉儲接口必須繼承IRepository<>接口

/// <summary>
/// 產品倉儲接口
/// </summary>
public interface IProductRepository : IRepository<ProductEntity>
{
    /// <summary>
    /// 查詢
    /// </summary>
    /// <param name="model"></param>
    /// <returns></returns>
    Task<IList<ProductEntity>> Query(ProductQueryModel model);
}

四、添加查詢模型

查詢模型包含查詢條件,須要繼承QueryModel類,該類包含了分頁相關的信息

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

五、添加倉儲實現

倉儲實現須要繼承抽象倉儲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;
    }
}

上面的例子是一個最簡單的分頁查詢,到此數據訪問的代碼就寫完了,剩下的就是在服務層調用就好了。

其它用法說明

一、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();
    }
}

好了,數據庫訪問的用法大體就是這樣~

相關文章
相關標籤/搜索