OsharpNS轻量级.net core快速开发框架简明入门教程-基于Osharp实现自己的业务功能

时间:2022-10-12 06:13:23

OsharpNS轻量级.net core快速开发框架简明入门教程

教程目录

  1. 从零开始启动Osharp

    1.1. 使用OsharpNS项目模板创建项目

    1.2. 配置数据库连接串并启动项目

    1.3. OsharpNS.Swagger使用实例(登录和授权)

    1.4. Angular6的前端项目启动

  2. Osharp代码生成器的使用

    2.1 生成器的使用

    2.2 生成代码详解(如何自己实现业务功能)

  3. Osharp部分模块使用

    3.1 Osharp.Redis使用

    3.2 Osharp.Hangfire使用

    3.3 Osharp.Permissions使用

  4. Osharp深度学习和使用

    4.1 切换数据库(从SqlServer改为MySql)

    4.2 多上下文配置(多个数据库的使用)

    4.3. 自定义模块的定义(Senparc.Weixin的使用)

    4.4. 继续学习中....

OsharpNS官方资源

项目地址:https://github.com/i66soft/osharp-ns20

演示地址:https://www.osharp.org 直接使用QQ登录可以查看效果

文档地址:https://docs.osharp.org 正在完善中....

发布博客:https://www.cnblogs.com/guomingfeng/p/osharpns-publish.html 大神看这个文档应该就能跑起来,从零开始启动Osharp基于此文档完成

VS生成器插件:https://marketplace.visualstudio.com/items?itemName=LiuliuSoft.osharp

官方交流QQ群:85895249

基于Osharp实现自己的业务功能

目录

  1. 基于Osharp实现业务的编码流程

  2. Core模块代码

  3. EntityConfiguration模块代码

  4. WebApi模块代码

基于Osharp实现业务的编码流程

本篇基于教程前面的项目和生成的代码展开,CanDoo.Test是使用项目模板创建的项目命名空间,CMS是使用生成器创建的内容管理模块,如不明白,请看前面的教程。

  1. 根据业务需求,确定需要开发的模块,和各个模块需要的实体及实体属性

  2. 根据业务需要分模块定义实体属性,位于CanDoo.Test.Core/CMS/Entities

  3. 根据实体的定义,完成实体各属性的数据库配置,位于CanDoo.Test.EntityConfiguration/CMS/

  4. 根据业务需要定义输入、输出Dto,位于CanDoo.Test.Core/CMS/Dtos

  5. 根据业务需要定义此实体对应的功能接口,位于CanDoo.Test.Core/CMS

  6. 根据业务需求实现功能,位于CanDoo.Test.Core/CMS

  7. 新建一个自定义模块,完成接口和服务的依赖注入,位于CanDoo.Test.Core/CMS

  8. 新建一个控制器,调用对应模块的接口,定义对应功能的WebApi,前端调用WebApi完成用户界面,位于CanDoo.Test.Web/Areas/Admin/Controllers/CMS

  9. 下图为接下去讲解代码在项目中的位置,很多文件以.generated.cs,此文件为代码自动生成的模板代码,实现了基础的增删改查操作,当使用生成器重新生成代码时,此文件会被覆盖,如果实现代码需要改动,不建议直接在此文件上改动,建议新建一个文件,继承自以.generated.cs结尾的文件,在新文件中改动相关的实现,从而避免重新生成代码,导致自定义代码被覆盖

    OsharpNS轻量级.net core快速开发框架简明入门教程-基于Osharp实现自己的业务功能

    OsharpNS轻量级.net core快速开发框架简明入门教程-基于Osharp实现自己的业务功能

Core模块代码

接下去以CMS模块中的Article为了来讲解相关代码

  1. 实体的定义:

    EntityBase:定义了主键Id的类型为int

    ILockable:定义可锁定功能,需定义属性:IsLocked

    ISoftDeletable:定义逻辑删除功能,需定义属性:DeletedTime

    ICreationAudited:定义创建审计信息,需定义属性:CreatorId,CreatedTime

    IUpdateAudited:定义更新审计信息,需定义属性:LastUpdaterId,LastUpdatedTime

    //------------------------------------------------------------------------------
    // <auto-generated>
    // 此代码由代码生成器生成。
    // 手动更改此文件可能导致应用程序出现意外的行为。
    // 如果重新生成代码,对此文件的任何修改都会丢失。
    // 如果需要扩展此类,请新建分部类 partial class Article 进行扩展
    // </auto-generated>
    //
    // <copyright file="Article.generated.cs" company="杭州乾渡科技有限公司">
    // Copyright 2019 乾渡科技出品
    // </copyright>
    // <site>https://www.osharp.org</site>
    // <last-editor>atai</last-editor>
    // <last-date>2019-04-27 10:04</last-date>
    // ----------------------------------------------------------------------- using System;
    using System.Collections.Generic;
    using System.ComponentModel; using OSharp.Entity; using CanDoo.Test.Identity.Entities; namespace CanDoo.Test.CMS.Entities { /// <summary>
    /// 实体类:文章信息
    /// </summary>
    [Description("文章信息")]
    public partial class Article : EntityBase<int>, ILockable, ISoftDeletable, ICreationAudited<int>, IUpdateAudited<int>
    {
    /// <summary>
    /// 获取或设置 标题
    /// </summary>
    [DisplayName("标题")]
    public string Title { get; set; } /// <summary>
    /// 获取或设置 内容
    /// </summary>
    [DisplayName("内容")]
    public string Content { get; set; } /// <summary>
    /// 获取或设置 是否锁定
    /// </summary>
    [DisplayName("是否锁定")]
    public bool IsLocked { get; set; } /// <summary>
    /// 获取或设置 删除时间
    /// </summary>
    [DisplayName("删除时间")]
    public DateTime? DeletedTime { get; set; } /// <summary>
    /// 获取或设置 创建者
    /// </summary>
    [DisplayName("创建者")]
    public int? CreatorId { get; set; } /// <summary>
    /// 获取或设置 创建时间
    /// </summary>
    [DisplayName("创建时间")]
    public DateTime CreatedTime { get; set; } /// <summary>
    /// 获取或设置 更新者
    /// </summary>
    [DisplayName("更新者")]
    public int? LastUpdaterId { get; set; } /// <summary>
    /// 获取或设置 更新时间
    /// </summary>
    [DisplayName("更新时间")]
    public DateTime? LastUpdatedTime { get; set; } /// <summary>
    /// 获取或设置 分类外键
    /// </summary>
    [DisplayName("分类外键")]
    public int ArticleCategoryId { get; set; } /// <summary>
    /// 获取或设置 发布人外键
    /// </summary>
    [DisplayName("发布人外键")]
    public int? UserId { get; set; } /// <summary>
    /// 获取或设置 分类
    /// </summary>
    [DisplayName("分类")]
    public virtual ArticleCategory ArticleCategory { get; set; } /// <summary>
    /// 获取或设置 发布人
    /// </summary>
    [DisplayName("发布人")]
    public virtual User User { get; set; } } }
  2. InputDto的定义:此Dto用于向系统输入数据的时候,比如新增数据,编辑数据时,通过InputDto来提供数据

    IInputDto:定义了主键类型为int


    // -----------------------------------------------------------------------
    // <auto-generated>
    // 此代码由代码生成器生成。
    // 手动更改此文件可能导致应用程序出现意外的行为。
    // 如果重新生成代码,对此文件的任何修改都会丢失。
    // 如果需要扩展此类,请新建分部类 partial class ArticleInputDto 进行扩展
    // </auto-generated>
    //
    // <copyright file="ArticleInputDto.generated.cs" company="杭州乾渡科技有限公司">
    // Copyright 2019 乾渡科技出品
    // </copyright>
    // <site>https://www.osharp.org</site>
    // <last-editor>atai</last-editor>
    // <last-date>2019-04-27 10:04</last-date>
    // ----------------------------------------------------------------------- using System;
    using System.ComponentModel;
    using System.ComponentModel.DataAnnotations; using OSharp.Entity;
    using OSharp.Mapping; using CanDoo.Test.CMS.Entities; namespace CanDoo.Test.CMS.Dtos
    {
    /// <summary>
    /// 输入DTO:文章信息
    /// </summary>
    [MapTo(typeof(Article))]
    [Description("文章信息")]
    public partial class ArticleInputDto : IInputDto<int>
    {
    /// <summary>
    /// 获取或设置 编号
    /// </summary>
    [DisplayName("编号")]
    public int Id { get; set; } /// <summary>
    /// 获取或设置 分类外键
    /// </summary>
    [DisplayName("分类外键")]
    public int ArticleCategoryId { get; set; } /// <summary>
    /// 获取或设置 标题
    /// </summary>
    [DisplayName("标题")]
    public string Title { get; set; } /// <summary>
    /// 获取或设置 内容
    /// </summary>
    [DisplayName("内容")]
    public string Content { get; set; } /// <summary>
    /// 获取或设置 发布人外键
    /// </summary>
    [DisplayName("发布人外键")]
    public int UserId { get; set; } /// <summary>
    /// 获取或设置 是否锁定
    /// </summary>
    [DisplayName("是否锁定")]
    public bool IsLocked { get; set; } } }
  3. OutDto的定义:此Dto用于输出数据给用户时候,比如数据列表展示,展示数据详情的时候,通过OutDto来提供数据

    IDataAuthEnabled:定义数据权限的允许更新,允许删除状态,需定义:Updatable,Deletable

    // -----------------------------------------------------------------------
    // <auto-generated>
    // 此代码由代码生成器生成。
    // 手动更改此文件可能导致应用程序出现意外的行为。
    // 如果重新生成代码,对此文件的任何修改都会丢失。
    // 如果需要扩展此类,请新建分部类 partial class ArticleOutputDto 进行扩展
    // </auto-generated>
    //
    // <copyright file="ArticleOutputDto.generated.cs" company="杭州乾渡科技有限公司">
    // Copyright 2019 乾渡科技出品
    // </copyright>
    // <site>https://www.osharp.org</site>
    // <last-editor>atai</last-editor>
    // <last-date>2019-04-27 10:04</last-date>
    // ----------------------------------------------------------------------- using System;
    using System.ComponentModel;
    using System.ComponentModel.DataAnnotations; using OSharp.Entity;
    using OSharp.Mapping; using CanDoo.Test.CMS.Entities;
    using CanDoo.Test.Identity.Entities; namespace CanDoo.Test.CMS.Dtos
    {
    /// <summary>
    /// 输入DTO:文章信息
    /// </summary>
    [MapFrom(typeof(Article))]
    [Description("文章信息")]
    public partial class ArticleOutputDto : IOutputDto, IDataAuthEnabled
    {
    /// <summary>
    /// 获取或设置 编号
    /// </summary>
    [DisplayName("编号")]
    public int Id { get; set; } /// <summary>
    /// 获取或设置 分类
    /// </summary>
    [DisplayName("分类")]
    public ArticleCategory ArticleCategory { get; set; } /// <summary>
    /// 获取或设置 标题
    /// </summary>
    [DisplayName("标题")]
    public string Title { get; set; } /// <summary>
    /// 获取或设置 内容
    /// </summary>
    [DisplayName("内容")]
    public string Content { get; set; } /// <summary>
    /// 获取或设置 发布人
    /// </summary>
    [DisplayName("发布人")]
    public User User { get; set; } /// <summary>
    /// 获取或设置 是否锁定
    /// </summary>
    [DisplayName("是否锁定")]
    public bool IsLocked { get; set; } /// <summary>
    /// 获取或设置 创建者
    /// </summary>
    [DisplayName("创建者")]
    public int CreatorId { get; set; } /// <summary>
    /// 获取或设置 创建时间
    /// </summary>
    [DisplayName("创建时间")]
    public DateTime CreatedTime { get; set; } /// <summary>
    /// 获取或设置 更新者
    /// </summary>
    [DisplayName("更新者")]
    public int LastUpdaterId { get; set; } /// <summary>
    /// 获取或设置 更新时间
    /// </summary>
    [DisplayName("更新时间")]
    public DateTime LastUpdatedTime { get; set; } /// <summary>
    /// 获取或设置 是否可更新的数据权限状态
    /// </summary>
    public bool Updatable { get; set; } /// <summary>
    /// 获取或设置 是否可删除的数据权限状态
    /// </summary>
    public bool Deletable { get; set; } } }
  4. 接口的定义:定义需要的接口

    // -----------------------------------------------------------------------
    // <auto-generated>
    // 此代码由代码生成器生成。
    // 手动更改此文件可能导致应用程序出现意外的行为。
    // 如果重新生成代码,对此文件的任何修改都会丢失。
    // 如果需要扩展此接口,请新建分部接口 partial interface ICMSContract 添加新的方法,并添加相应新的分部基类 abstract partial class CMSServiceBase 实现新方法
    // </auto-generated>
    //
    // <copyright file="ICMSContract.generated.cs" company="杭州乾渡科技有限公司">
    // Copyright 2019 乾渡科技出品
    // </copyright>
    // <site>https://www.osharp.org</site>
    // <last-editor>atai</last-editor>
    // <last-date>2019-04-27 10:04</last-date>
    // ----------------------------------------------------------------------- using System;
    using System.Linq;
    using System.Linq.Expressions;
    using System.Threading.Tasks; using OSharp.Data;
    using OSharp.Extensions; using CanDoo.Test.CMS.Dtos;
    using CanDoo.Test.CMS.Entities; namespace CanDoo.Test.CMS
    {
    /// <summary>
    /// 业务契约接口:内容管理模块
    /// </summary>
    public partial interface ICMSContract
    { #region 文章分类信息业务 #endregion #region 文章信息业务 /// <summary>
    /// 获取 文章信息查询数据集
    /// </summary>
    IQueryable<Article> Articles { get; } /// <summary>
    /// 检查文章信息信息是否存在
    /// </summary>
    /// <param name="predicate">检查谓语表达式</param>
    /// <param name="id">更新的文章信息编号</param>
    /// <returns>文章信息是否存在</returns>
    Task<bool> CheckArticleExists(Expression<Func<Article, bool>> predicate, int id = default(int)); /// <summary>
    /// 添加文章信息信息
    /// </summary>
    /// <param name="dtos">要添加的文章信息DTO信息</param>
    /// <returns>业务操作结果</returns>
    Task<OperationResult> CreateArticles(params ArticleInputDto[] dtos); /// <summary>
    /// 更新文章信息信息
    /// </summary>
    /// <param name="dtos">包含更新信息的文章信息DTO信息</param>
    /// <returns>业务操作结果</returns>
    Task<OperationResult> UpdateArticles(params ArticleInputDto[] dtos); /// <summary>
    /// 删除文章信息信息
    /// </summary>
    /// <param name="ids">要删除的文章信息编号</param>
    /// <returns>业务操作结果</returns>
    Task<OperationResult> DeleteArticles(params int[] ids); #endregion #region 留言板信息业务 #endregion } }
  5. 功能实现:因为一个功能模块中会有大量的实体,系统中将各个实体的具体实现进行了文件的拆分,从前面的图中可以看出,Article的具体实现位于CMSServiceBase.Article.generated.csCMSServiceBase.generated.cs定义了CMS模块所有需要使用到的对象,CMSService.cs为模块的业务实现基类

   // -----------------------------------------------------------------------
// <auto-generated>
// 此代码由代码生成器生成。
// 手动更改此文件可能导致应用程序出现意外的行为。
// 如果重新生成代码,对此文件的任何修改都会丢失。
// 如果需要扩展此类,可以遵守如下规则进行扩展:
// 1.横向扩展:如需给当前实体 Article 添加方法,可新建文件“CMSServiceBase.Article.cs”的分部类“public abstract partial class CMSServiceBase”添加功能
// 2.纵向扩展:如需要重写当前实体 Article 的业务实现,可新建文件“CMSService.Article.cs”的分部类“public partial class CMSService”对现有方法进行方法重写实现
// </auto-generated>
//
// <copyright file="CMSServiceBase.Article.generated.cs" company="杭州乾渡科技有限公司">
// Copyright 2019 乾渡科技出品
// </copyright>
// <site>https://www.osharp.org</site>
// <last-editor>atai</last-editor>
// <last-date>2019-04-27 10:04</last-date>
// ----------------------------------------------------------------------- using System;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks; using OSharp.Data;
using OSharp.Dependency;
using OSharp.Extensions;
using OSharp.Mapping; using CanDoo.Test.CMS.Dtos;
using CanDoo.Test.CMS.Entities; namespace CanDoo.Test.CMS
{
public abstract partial class CMSServiceBase
{
/// <summary>
/// 获取 文章信息查询数据集
/// </summary>
public IQueryable<Article> Articles
{
get { return ArticleRepository.Query(); }
} /// <summary>
/// 检查文章信息是否存在
/// </summary>
/// <param name="predicate">检查谓语表达式</param>
/// <param name="id">更新的文章信息编号</param>
/// <returns>文章信息是否存在</returns>
public virtual Task<bool> CheckArticleExists(Expression<Func<Article, bool>> predicate, int id = default(int))
{
return ArticleRepository.CheckExistsAsync(predicate, id);
} /// <summary>
/// 添加文章信息
/// </summary>
/// <param name="dtos">要添加的文章信息DTO信息</param>
/// <returns>业务操作结果</returns>
public virtual Task<OperationResult> CreateArticles(params ArticleInputDto[] dtos)
{
Check.NotNull(dtos, nameof(dtos));
return ArticleRepository.InsertAsync(dtos);
} /// <summary>
/// 更新文章信息
/// </summary>
/// <param name="dtos">包含更新信息的文章信息DTO信息</param>
/// <returns>业务操作结果</returns>
public virtual Task<OperationResult> UpdateArticles(params ArticleInputDto[] dtos)
{
Check.NotNull(dtos, nameof(dtos));
return ArticleRepository.UpdateAsync(dtos);
} /// <summary>
/// 删除文章信息
/// </summary>
/// <param name="ids">要删除的文章信息编号</param>
/// <returns>业务操作结果</returns>
public virtual Task<OperationResult> DeleteArticles(params int[] ids)
{
Check.NotNull(ids, nameof(ids));
return ArticleRepository.DeleteAsync(ids);
}
} }

// -----------------------------------------------------------------------
// <auto-generated>
// 此代码由代码生成器生成。
// 手动更改此文件可能导致应用程序出现意外的行为。
// 如果重新生成代码,对此文件的任何修改都会丢失。
// 如果需要扩展此类,请在控制器类型 CMSService 进行继承重写
// </auto-generated>
//
// <copyright file="ICMSServiceBase.generated.cs" company="杭州乾渡科技有限公司">
// Copyright 2019 乾渡科技出品
// </copyright>
// <site>https://www.osharp.org</site>
// <last-editor>atai</last-editor>
// <last-date>2019-04-27 10:04</last-date>
// ----------------------------------------------------------------------- using System;
using System.Linq;
using System.Threading.Tasks; using OSharp.Core.Systems;
using OSharp.Data;
using OSharp.Entity;
using OSharp.EventBuses;
using OSharp.Extensions;
using OSharp.Identity; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using CanDoo.Test.CMS.Dtos;
using CanDoo.Test.CMS.Entities; namespace CanDoo.Test.CMS
{
/// <summary>
/// 业务实现基类:内容管理模块
/// </summary>
public abstract partial class CMSServiceBase : ICMSContract
{
/// <summary>
/// 初始化一个<see cref="CMSService"/>类型的新实例
/// </summary>
protected CMSServiceBase(IServiceProvider provider)
{
ServiceProvider = provider;
Logger = provider.GetLogger(GetType());
} #region 属性 /// <summary>
/// 获取或设置 服务提供者对象
/// </summary>
protected IServiceProvider ServiceProvider { get; } /// <summary>
/// 获取或设置 日志对象
/// </summary>
protected ILogger Logger { get; } /// <summary>
/// 获取或设置 文章分类信息仓储对象
/// </summary>
protected IRepository<ArticleCategory, int> ArticleCategoryRepository => ServiceProvider.GetService<IRepository<ArticleCategory, int>>(); /// <summary>
/// 获取或设置 文章信息仓储对象
/// </summary>
protected IRepository<Article, int> ArticleRepository => ServiceProvider.GetService<IRepository<Article, int>>(); /// <summary>
/// 获取或设置 留言板信息仓储对象
/// </summary>
protected IRepository<MessageBoard, int> MessageBoardRepository => ServiceProvider.GetService<IRepository<MessageBoard, int>>(); /// <summary>
/// 获取 事件总线
/// </summary>
protected IEventBus EventBus => ServiceProvider.GetService<IEventBus>(); /// <summary>
/// 获取 设置存储对象
/// </summary>
protected IKeyValueStore KeyValueStore => ServiceProvider.GetService<IKeyValueStore>(); #endregion
} }
   // -----------------------------------------------------------------------
// <once-generated>
// 这个文件只生成一次,再次生成不会被覆盖。
// 可以在此类进行继承重写来扩展基类 CMSServiceBase
// </once-generated>
//
// <copyright file="ICMSService.cs" company="Qiadoo">
// 随便用
// </copyright>
// <site>http://www.qiadoo.com</site>
// <last-editor>atai</last-editor>
// <last-date>2019-04-26 13:52</last-date>
// ----------------------------------------------------------------------- using System; namespace CanDoo.Test.CMS
{
/// <summary>
/// 业务实现基类:内容管理模块
/// </summary>
public partial class CMSService : CMSServiceBase
{
/// <summary>
/// 初始化一个<see cref="CMSService"/>类型的新实例
/// </summary>
public CMSService(IServiceProvider provider)
: base(provider)
{ }
}
}
  1. 模块定义:将模块服务添加到依赖注入服务容器中

    OsharpPack:系统启动的时候会自动查找继承自OsharpPack的模块,完成加载

   // -----------------------------------------------------------------------
// <auto-generated>
// 此代码由代码生成器生成。
// 手动更改此文件可能导致应用程序出现意外的行为。
// 如果重新生成代码,对此文件的任何修改都会丢失。
// 如果需要扩展此类,请新建分部类 partial class CMSPack 进行实现分部方法 AddServicesAppend,UsePackAppend 进行扩展
// </auto-generated>
//
// <copyright file="ICMSPack.generated.cs" company="杭州乾渡科技有限公司">
// Copyright 2019 乾渡科技出品
// </copyright>
// <site>https://www.osharp.org</site>
// <last-editor>atai</last-editor>
// <last-date>2019-04-27 10:04</last-date>
// ----------------------------------------------------------------------- using System;
using System.ComponentModel; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions; using OSharp.Core.Packs; namespace CanDoo.Test.CMS
{
/// <summary>
/// 内容管理模块
/// </summary>
[Description("内容管理模块")]
public partial class CMSPack : OsharpPack
{
/// <summary>将模块服务添加到依赖注入服务容器中</summary>
/// <param name="services">依赖注入服务容器</param>
/// <returns></returns>
public override IServiceCollection AddServices(IServiceCollection services)
{
services.TryAddScoped<ICMSContract, CMSService>();
AddServicesAppend(services); return services;
} /// <summary>
/// 额外的服务注册
/// </summary>
/// <param name="services">依赖注入服务容器</param>
partial void AddServicesAppend(IServiceCollection services); /// <summary>
/// 应用模块服务
/// </summary>
/// <param name="provider">服务提供者</param>
public override void UsePack(IServiceProvider provider)
{
UsePackAppend(provider); base.UsePack(provider);
} /// <summary>
/// 额外的服务注册
/// </summary>
/// <param name="provider">服务提供者</param>
partial void UsePackAppend(IServiceProvider provider);
} }

EntityConfiguration模块代码解析

直接贴代码了,在这里完成了各个属性的数据库配置,以下2行都是多对一的配置,第一条是文章和文章分类实现双向导航,第二条是文章和用户的单向导航,当然在这里还能指定表的名称等等,反正数据库想怎么配置就在这里折腾吧

builder.HasOne<ArticleCategory>(m => m.ArticleCategory).WithMany(n => n.Articles).HasForeignKey(m => m.ArticleCategoryId).IsRequired().OnDelete(DeleteBehavior.Restrict);
builder.HasOne<User>(m => m.User).WithMany().HasForeignKey(m => m.UserId).IsRequired().OnDelete(DeleteBehavior.Restrict);
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由代码生成器生成。
// 手动更改此文件可能导致应用程序出现意外的行为。
// 如果重新生成代码,对此文件的任何修改都会丢失。
// 如果需要扩展此类,请新建分部类 partial class ArticleConfiguration 实现分部方法 EntityConfigurationAppend 进行扩展
// </auto-generated>
//
// <copyright file="ArticleConfiguration.generated.cs" company="杭州乾渡科技有限公司">
// Copyright 2019 乾渡科技出品
// </copyright>
// <site>https://www.osharp.org</site>
// <last-editor>atai</last-editor>
// <last-date>2019-04-27 10:04</last-date>
// ----------------------------------------------------------------------- using System; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders; using OSharp.Entity; using CanDoo.Test.CMS.Entities;
using CanDoo.Test.Identity.Entities; namespace CanDoo.Test.EntityConfiguration.CMS
{
/// <summary>
/// 实体配置类:文章信息
/// </summary>
public partial class ArticleConfiguration : EntityTypeConfigurationBase<Article, int>
{
/// <summary>
/// 重写以实现实体类型各个属性的数据库配置
/// </summary>
/// <param name="builder">实体类型创建器</param>
public override void Configure(EntityTypeBuilder<Article> builder)
{
builder.HasOne<ArticleCategory>(m => m.ArticleCategory).WithMany(n => n.Articles).HasForeignKey(m => m.ArticleCategoryId).IsRequired().OnDelete(DeleteBehavior.Restrict);
builder.HasOne<User>(m => m.User).WithMany().HasForeignKey(m => m.UserId).IsRequired().OnDelete(DeleteBehavior.Restrict); EntityConfigurationAppend(builder);
} /// <summary>
/// 额外的数据映射
/// </summary>
partial void EntityConfigurationAppend(EntityTypeBuilder<Article> builder);
} }

WebApi模块代码

还是没啥说的,自己看代码吧,注意看下对AdminApiController的继承,


// -----------------------------------------------------------------------
// <copyright file="AdminApiController.cs" company="OSharp开源团队">
// Copyright (c) 2014-2018 OSharp. All rights reserved.
// </copyright>
// <site>http://www.osharp.org</site>
// <last-editor>郭明锋</last-editor>
// <last-date>2018-06-27 4:50</last-date>
// ----------------------------------------------------------------------- using Microsoft.AspNetCore.Mvc; using OSharp.AspNetCore.Mvc;
using OSharp.Core; namespace CanDoo.Test.Web.Areas.Admin.Controllers
{
[Area("Admin")]
[RoleLimit]//继承了这个,就会进行权限检查 public abstract class AdminApiController : AreaApiController
{ } }

// -----------------------------------------------------------------------
// <auto-generated>
// 此代码由代码生成器生成。
// 手动更改此文件可能导致应用程序出现意外的行为。
// 如果重新生成代码,对此文件的任何修改都会丢失。
// 如果需要扩展此类,请在控制器类型 ArticleController 进行继承重写
// </auto-generated>
//
// <copyright file="ArticleBase.generated.cs" company="杭州乾渡科技有限公司">
// Copyright 2019 乾渡科技出品
// </copyright>
// <site>https://www.osharp.org</site>
// <last-editor>atai</last-editor>
// <last-date>2019-04-27 10:04</last-date>
// ----------------------------------------------------------------------- using System;
using System.ComponentModel;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using OSharp.AspNetCore.Mvc;
using OSharp.AspNetCore.Mvc.Filters;
using OSharp.AspNetCore.UI;
using OSharp.Caching;
using OSharp.Core.Functions;
using OSharp.Core.Modules;
using OSharp.Data;
using OSharp.Entity;
using OSharp.Filter;
using OSharp.Secutiry; using CanDoo.Test.CMS;
using CanDoo.Test.CMS.Dtos;
using CanDoo.Test.CMS.Entities; namespace CanDoo.Test.Web.Areas.Admin.Controllers
{
/// <summary>
/// 管理控制器基类: 文章信息
/// </summary>
[ModuleInfo(Position = "CMS", PositionName = "内容管理模块")]
[Description("管理-文章信息")]
public abstract class ArticleControllerBase : AdminApiController
{
/// <summary>
/// 初始化一个<see cref="ArticleController"/>类型的新实例
/// </summary>
protected ArticleControllerBase(ICMSContract cMSContract,
IFilterService filterService)
{
CMSContract = cMSContract;
FilterService = filterService;
} /// <summary>
/// 获取或设置 数据过滤服务对象
/// </summary>
protected IFilterService FilterService { get; } /// <summary>
/// 获取或设置 内容管理模块业务契约对象
/// </summary>
protected ICMSContract CMSContract { get; } /// <summary>
/// 读取文章列表信息
/// </summary>
/// <param name="request">页请求信息</param>
/// <returns>文章列表分页信息</returns>
[HttpPost]
[ModuleInfo]
[Description("读取")]
public virtual PageData<ArticleOutputDto> Read(PageRequest request)
{
Check.NotNull(request, nameof(request)); Expression<Func<Article, bool>> predicate = FilterService.GetExpression<Article>(request.FilterGroup);
var page = CMSContract.Articles.ToPage<Article, ArticleOutputDto>(predicate, request.PageCondition); return page.ToPageData();
} /// <summary>
/// 新增文章信息
/// </summary>
/// <param name="dtos">文章信息输入DTO</param>
/// <returns>JSON操作结果</returns>
[HttpPost]
[ModuleInfo]
[DependOnFunction("Read")]
[ServiceFilter(typeof(UnitOfWorkAttribute))]
[Description("新增")]
public virtual async Task<AjaxResult> Create(ArticleInputDto[] dtos)
{
Check.NotNull(dtos, nameof(dtos));
OperationResult result = await CMSContract.CreateArticles(dtos);
return result.ToAjaxResult();
} /// <summary>
/// 更新文章信息
/// </summary>
/// <param name="dtos">文章信息输入DTO</param>
/// <returns>JSON操作结果</returns>
[HttpPost]
[ModuleInfo]
[DependOnFunction("Read")]
[ServiceFilter(typeof(UnitOfWorkAttribute))]
[Description("更新")]
public virtual async Task<AjaxResult> Update(ArticleInputDto[] dtos)
{
Check.NotNull(dtos, nameof(dtos));
OperationResult result = await CMSContract.UpdateArticles(dtos);
return result.ToAjaxResult();
} /// <summary>
/// 删除文章信息
/// </summary>
/// <param name="ids">文章信息编号</param>
/// <returns>JSON操作结果</returns>
[HttpPost]
[ModuleInfo]
[DependOnFunction("Read")]
[ServiceFilter(typeof(UnitOfWorkAttribute))]
[Description("删除")]
public virtual async Task<AjaxResult> Delete(int[] ids)
{
Check.NotNull(ids, nameof(ids));
OperationResult result = await CMSContract.DeleteArticles(ids);
return result.ToAjaxResult();
}
} }

// -----------------------------------------------------------------------
// <once-generated>
// 这个文件只生成一次,再次生成不会被覆盖。
// 可以在此类进行继承重写来扩展基类 ArticleControllerBase
// </once-generated>
//
// <copyright file="Article.cs" company="Qiadoo">
// 随便用
// </copyright>
// <site>http://www.qiadoo.com</site>
// <last-editor>atai</last-editor>
// <last-date>2019-04-26 13:52</last-date>
// ----------------------------------------------------------------------- using System; using OSharp.Filter; using CanDoo.Test.CMS; namespace CanDoo.Test.Web.Areas.Admin.Controllers
{
/// <summary>
/// 管理控制器: 文章信息
/// </summary>
public class ArticleController : ArticleControllerBase
{
/// <summary>
/// 初始化一个<see cref="ArticleController"/>类型的新实例
/// </summary>
public ArticleController(ICMSContract cMSContract,
IFilterService filterService)
: base(cMSContract, filterService)
{ }
}
}