.NET 9.0 的 Blazor Web App 项目、Bootstrap Blazor 组件库、自定义日志 TLog 使用备忘

一、设计目标:通用、容易修改、使用简单,所有代码保存在一个文件中,方便移植到其他项目使用。

注:示例使用 Bootstrap Blazor 组件库和 EF Core 、Sqlite,需要先使用 Nuget包管理器 添加对应的包。

cs 复制代码
namespace BlazorWebAppNet9Shared.Services;

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using System.ComponentModel.DataAnnotations;

/// <summary>
/// 日志记录服务。<br/><br/>
/// 使用示例,第1步:builder.Services.AddTLog("Data Source=SQLiteFileLog.db");<br/>
/// 使用示例,第2步:TLog.Page(UserName, DisplayName, NavigationManager.ToBaseRelativePath(NavigationManager.Uri));
/// </summary>
public static class TLog
{
    public static TLogDbContext TLogDb { get; set; } = default!;

    /// <summary>
    /// 添加 TLog 服务。<br/>
    /// 示例:builder.Services.AddTLog("Data Source=SQLiteFileLog.db");
    /// </summary>
    /// <param name="services"></param>
    /// <param name="ConnectionString"></param>
    /// <returns></returns>
    public static IServiceCollection AddTLog(this IServiceCollection services, string ConnectionString)
    {
        TLogDb = new TLogDbContext(ConnectionString);
        // 自动创建数据库和数据表:修改实体定义后,删除原有的数据库自动重新建立;或者根据实体定义手动修改数据库和数据表。
        TLogDb.Database.EnsureCreated();
        return services;
    }

    public static void Page(string 用户名, string 姓名, string 操作对象)
    {
        if (TLogDb != null)
        {
            TLogDb.Add(new TLogEntity() { 操作类型 = TLogOpStyle.浏览, 用户名 = 用户名, 姓名 = 姓名, 操作对象 = 操作对象 });
            TLogDb.SaveChanges();
        }
    }

    public static void Create(string 用户名, string 姓名, string 操作对象, string? 操作说明, bool 操作结果)
    {
        if (TLogDb != null)
        {
            TLogDb.Add(new TLogEntity() { 操作类型 = TLogOpStyle.新建, 用户名 = 用户名, 姓名 = 姓名, 操作对象 = 操作对象, 操作说明 = 操作说明, 操作结果 = 操作结果 });
            TLogDb.SaveChanges();
        }
    }

    public static void Delete(string 用户名, string 姓名, string 操作对象, string? 操作说明, bool 操作结果)
    {
        if (TLogDb != null)
        {
            TLogDb.Add(new TLogEntity() { 操作类型 = TLogOpStyle.删除, 用户名 = 用户名, 姓名 = 姓名, 操作对象 = 操作对象, 操作说明 = 操作说明, 操作结果 = 操作结果 });
            TLogDb.SaveChanges();
        }
    }

    public static void Update(string 用户名, string 姓名, string 操作对象, string? 操作说明, bool 操作结果)
    {
        if (TLogDb != null)
        {
            TLogDb.Add(new TLogEntity() { 操作类型 = TLogOpStyle.编辑, 用户名 = 用户名, 姓名 = 姓名, 操作对象 = 操作对象, 操作说明 = 操作说明, 操作结果 = 操作结果 });
            TLogDb.SaveChanges();
        }
    }

    public static void Read(string 用户名, string 姓名, string 操作对象, string? 操作说明, bool 操作结果)
    {
        if (TLogDb != null)
        {
            TLogDb.Add(new TLogEntity() { 操作类型 = TLogOpStyle.查询, 用户名 = 用户名, 姓名 = 姓名, 操作对象 = 操作对象, 操作说明 = 操作说明, 操作结果 = 操作结果 });
            TLogDb.SaveChanges();
        }
    }

}

/// <summary>
/// 日志数据库上下文:建立使用独立数据库,与业务数据分开存放。
/// </summary>
/// <param name="ConnectionString"></param>
public class TLogDbContext(string ConnectionString) : DbContext
{
    public DbSet<TLogEntity> TLogEntitys { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        base.OnConfiguring(optionsBuilder);
        optionsBuilder.UseSqlite(ConnectionString);
    }


    /* 建立索引:建立在实体定义时使用 Index 注解 建立,更方便。
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<TLogEntity>()
            .HasIndex(t => new { t.用户名, t.姓名, t.操作类型, t.操作对象 });

        modelBuilder.Entity<TLogEntity>()
            .HasIndex(t => new { t.用户名 });
    }*/
}

/// <summary>
/// 日志实体:后续可以根据需要增加,注意不要编辑、删除已有属性。
/// </summary>
[Index(nameof(Id))]
[Index(nameof(时间))]
[Index(nameof(用户名))]
[Index(nameof(姓名))]
[Index(nameof(操作类型))]
[Index(nameof(操作对象))]
[Index(nameof(姓名), nameof(操作对象))]
public class TLogEntity
{
    [Key]
    public long Id { get; set; }
    public DateTime 时间 { get; set; } = DateTime.Now;
    public required string 用户名 { get; set; }
    public required string 姓名 { get; set; }
    public TLogOpStyle 操作类型 { get; set; } = TLogOpStyle.浏览;
    public required string 操作对象 { get; set; }
    public string? 操作说明 { get; set; }
    public bool 操作结果 { get; set; } = true;

}

/// <summary>
/// 日志类型:后续可以根据需要增加,注意不要编辑、删除已有类型。
/// </summary>
public enum TLogOpStyle
{
    /// <summary>
    /// 用于记录访问路径:Page
    /// </summary>
    浏览,
    /// <summary>
    /// 增删改查CRUD:Create
    /// </summary>
    新建,
    /// <summary>
    /// 增删改查CRUD:Read
    /// </summary>
    查询,
    /// <summary>
    /// 增删改查CRUD:Update
    /// </summary>
    编辑,
    /// <summary>
    /// 增删改查CRUD:Delete
    /// </summary>
    删除,

}

代码文件:TLog.cs

二、使用步骤

1. 在 Program.cs 中添加 TLog 服务,同时指定保存日志的数据库文件名。

cs 复制代码
............

builder.Services.AddTLog("Data Source=SQLiteFileLog.db");

var app = builder.Build();

............

2. 在需要记录日志的位置,直接使用 TLog.Page 、TLog.Create 等静态方法进行记录,不需要进行注入、New等操作,简化代码输入。

cs 复制代码
    @inject NavigationManager NavigationManager;
    protected override void OnInitialized()
    {
        base.OnInitialized();
        // 记录日志
        TLog.Page(UserName, DisplayName, NavigationManager.ToBaseRelativePath(NavigationManager.Uri));
    }

3. 使用 TLogManager.razor 组件浏览日志

cs 复制代码
@page "/Log/TLogManager"

<Table TItem="TLogEntity" OnQueryAsync="@OnQueryAsync"
       AutoGenerateColumns=true HeaderStyle="TableHeaderStyle.Light"
       ClickToSelect="true" ShowLoading="true" AllowResizing="true"
       IsPagination="true" PageItemsSource="new int[] { 10, 20, 30, 60, 100 }"
       ShowToolbar="true" ShowDefaultButtons="false">
</Table>

@code {
    [CascadingParameter]
    public LayoutBB.MainLayout? mainLayout { get; set; }

    @inject NavigationManager NavigationManager;
    protected override void OnInitialized()
    {
        base.OnInitialized();
        // 记录日志
        TLog.Page(mainLayout?.UserName ?? "", mainLayout?.DisplayName ?? "", NavigationManager.ToBaseRelativePath(NavigationManager.Uri));
    }

    private async Task<QueryData<TLogEntity>> OnQueryAsync(QueryPageOptions options)
    {
        IEnumerable<TLogEntity> items = TLog.TLogDb.TLogEntitys.OrderByDescending(t => t.时间).ToList();
        var total = items.Count();
        items = items.Skip((options.PageIndex - 1) * options.PageItems).Take(options.PageItems).ToList();
        return await Task.FromResult(new QueryData<TLogEntity>() { Items = items, TotalCount = total, IsSorted = true, IsFiltered = true, IsSearch = true });
    }

}
相关推荐
island13141 小时前
【QT】 控件 -- 显示类
开发语言·数据库·qt
Andya_net2 小时前
网络安全 | F5-Attack Signatures-Set详解
网络·数据库·web安全
码农幻想梦3 小时前
实验二 数据库的附加/分离、导入/导出与备份/还原
数据库·oracle
hillstream33 小时前
Synology 群辉NAS安装(6)安装mssql
数据库·sqlserver
步、步、为营3 小时前
C# 探秘:PDFiumCore 开启PDF读取魔法之旅
开发语言·pdf·c#·.net
行十万里人生4 小时前
Qt 控件与布局管理
数据库·qt·microsoft·华为od·华为·华为云·harmonyos
betazhou4 小时前
sysbench压力测试工具mysql以及postgresql
数据库·mysql·postgresql
weixin_495774204 小时前
c# S7通信测试
开发语言·c#
莳花微语4 小时前
OGG 19C 集成模式启用DDL复制
数据库·oracle
潜水的码不二4 小时前
Redis高阶3-缓存双写一致性
数据库·redis·缓存