CmfDBCommon 1.0.0

dotnet add package CmfDBCommon --version 1.0.0
                    
NuGet\Install-Package CmfDBCommon -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="CmfDBCommon" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="CmfDBCommon" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="CmfDBCommon" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add CmfDBCommon --version 1.0.0
                    
#r "nuget: CmfDBCommon, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#addin nuget:?package=CmfDBCommon&version=1.0.0
                    
Install CmfDBCommon as a Cake Addin
#tool nuget:?package=CmfDBCommon&version=1.0.0
                    
Install CmfDBCommon as a Cake Tool

DBCommon 数据库通用组件

基于SqlSugar ORM的数据库通用访问组件,支持多种数据库,包括MySQL、SQL Server、Oracle、PostgreSQL和达梦数据库。

特点

  • 支持多种数据库类型
  • 基于工厂模式的设计
  • 完整的ORM操作支持
  • 灵活的配置管理
  • 支持事务处理
  • 支持原生SQL执行
  • 支持存储过程和函数调用
  • DBFirst实体生成器
  • 支持日志记录和自定义日志接口
  • 支持Microsoft日志系统集成
  • 完善的资源释放机制
  • 多线程环境下线程安全
  • 新增 - 分页查询支持
  • 新增 - 内存缓存支持
  • 新增 - 流式API查询构造器
  • 新增 - 高性能批量操作

安装

通过NuGet包管理器安装:

dotnet add package DBCommon

配置文件

默认配置文件为dbconfig.xml,位于程序根目录下。配置文件格式如下:

<?xml version="1.0" encoding="utf-8"?>
<DbConfig>
  <Connections>
    <Connection>
      <Name>default</Name>
      <DbType>MySql</DbType>
      <ConnectionString>server=localhost;database=testdb;uid=root;pwd=123456;charset=utf8;</ConnectionString>
      <IsMaster>true</IsMaster>
      <Enabled>true</Enabled>
    </Connection>
    <Connection>
      <Name>sqlserver</Name>
      <DbType>SqlServer</DbType>
      <ConnectionString>Server=.;Database=testdb;Trusted_Connection=True;</ConnectionString>
      <IsMaster>false</IsMaster>
      <Enabled>true</Enabled>
    </Connection>
  </Connections>
</DbConfig>

基本用法

初始化

// 使用默认配置和默认日志
var client = new DbCommonClient();

// 或指定配置文件路径
var client = new DbCommonClient("path/to/dbconfig.xml");

// 或指定配置文件路径和自定义日志
var logger = DbCommonClient.CreateDefaultLogger(
    minLevel: DefaultLogger.LogLevel.Debug,
    logFilePath: "logs/dbcommon.log",
    consoleOutput: true);
var client = new DbCommonClient("path/to/dbconfig.xml", logger);

// 或使用Microsoft日志系统
var msLogger = loggerFactory.CreateLogger<DbCommonClient>();
var client = new DbCommonClient("path/to/dbconfig.xml", msLogger);

// 或使用Microsoft日志工厂
var client = new DbCommonClient("path/to/dbconfig.xml", loggerFactory, "DBCommon.Client");

获取数据库上下文

// 获取默认数据库上下文
var db = client.GetDbContext();

// 获取指定名称的数据库上下文
var db = client.GetDbContext("sqlserver");

基本CRUD操作

// 插入
var entity = new User { Name = "张三", Age = 25 };
int insertId = await db.InsertAsync(entity);

// 查询 - 获取单个实体
var user = await db.GetByIdAsync<User>(1);

// 查询 - 获取列表
var list = await db.GetListAsync<User>(it => it.Age > 20);

// 查询 - 分页
var pageList = await db.GetPageListAsync<User>(it => it.Age > 20, 1, 10);

// 更新
user.Name = "李四";
await db.UpdateAsync(user);

// 删除
await db.DeleteAsync<User>(1);

事务处理

// 开始事务
db.BeginTran();

try 
{
    var user = new User { Name = "王五", Age = 30 };
    int userId = await db.InsertAsync(user);
    
    var log = new Log { UserId = userId, Content = "新用户注册" };
    await db.InsertAsync(log);
    
    // 提交事务
    db.CommitTran();
}
catch (Exception ex)
{
    // 回滚事务
    db.RollbackTran();
    throw;
}

原生SQL执行

// 执行SQL查询
var users = await db.SqlQueryAsync<User>("SELECT * FROM Users WHERE Age > @Age", new { Age = 25 });

// 执行SQL命令
int affectedRows = await db.ExecuteCommandAsync("UPDATE Users SET Status = 1 WHERE Id = @Id", new { Id = 1 });

配置管理功能

// 获取所有配置
var configs = client.GetAllConfigs();

// 获取特定配置
var config = client.GetConfig("default");

// 保存单个配置
var newConfig = new DbConnectionConfig
{
    Name = "oracle",
    DbType = Enums.DbType.Oracle,
    ConnectionString = "Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=ORCL)));User Id=system;Password=oracle;",
    IsMaster = false,
    Enabled = true
};
client.SaveConfig(newConfig);

// 保存多个配置
var configList = new List<DbConnectionConfig>
{
    new DbConnectionConfig
    {
        Name = "pg",
        DbType = Enums.DbType.PostgreSQL,
        ConnectionString = "Host=localhost;Port=5432;Database=testdb;Username=postgres;Password=postgres",
        IsMaster = false,
        Enabled = true
    },
    new DbConnectionConfig
    {
        Name = "dameng",
        DbType = Enums.DbType.Dameng,
        ConnectionString = "Server=localhost;Port=5236;User=SYSDBA;Password=SYSDBA;Database=DAMENG",
        IsMaster = false,
        Enabled = true
    }
};
client.SaveConfigs(configList);

// 删除配置
client.DeleteConfig("dameng");

// 确保配置存在(如果不存在则创建默认配置)
client.EnsureConfigExists();

日志功能

// 创建并设置默认日志(控制台输出 + 文件输出)
var logger = DbCommonClient.CreateDefaultLogger(
    minLevel: DefaultLogger.LogLevel.Debug,
    logFilePath: "logs/dbcommon.log",
    consoleOutput: true);
DbCommonClient.SetDefaultLogger(logger);

// 创建指定名称的日志实例
var sqlLogger = DbCommonClient.CreateDefaultLogger(
    minLevel: DefaultLogger.LogLevel.Info,
    logFilePath: "logs/sql.log");
DbCommonClient.RegisterLogger("SQL", sqlLogger);

// 获取指定名称的日志实例
var logger = DbCommonClient.GetLogger("SQL");
logger.Info("执行SQL查询");

// 创建空日志(不输出任何日志)
var nullLogger = DbCommonClient.CreateNullLogger();

// 使用自定义日志实现
// 首先实现ILogger接口
public class MyCustomLogger : ILogger
{
    public void Debug(string message, params object[] args) { /* 自定义实现 */ }
    public void Info(string message, params object[] args) { /* 自定义实现 */ }
    public void Warning(string message, params object[] args) { /* 自定义实现 */ }
    public void Error(string message, params object[] args) { /* 自定义实现 */ }
    public void Error(Exception exception, string message, params object[] args) { /* 自定义实现 */ }
    public void Fatal(string message, params object[] args) { /* 自定义实现 */ }
    public void Fatal(Exception exception, string message, params object[] args) { /* 自定义实现 */ }
}

// 然后注册并使用
var myLogger = new MyCustomLogger();
DbCommonClient.SetDefaultLogger(myLogger);

// 或者在创建客户端时直接使用
var client = new DbCommonClient(logger: myLogger);

Microsoft日志系统集成

// 在ASP.NET Core或使用Microsoft.Extensions.Logging的项目中集成

// 依赖注入方式
// 在Startup.cs或Program.cs中
services.AddLogging(builder => 
{
    builder.AddConsole();
    builder.AddDebug();
});

// 在控制器或服务中注入
public class MyService
{
    private readonly DbCommonClient _dbClient;
    
    public MyService(ILoggerFactory loggerFactory)
    {
        // 方法1:使用Microsoft ILogger创建DbCommonClient
        var logger = loggerFactory.CreateLogger<MyService>();
        _dbClient = new DbCommonClient("path/to/dbconfig.xml", logger);
        
        // 方法2:使用Microsoft ILoggerFactory创建DbCommonClient
        _dbClient = new DbCommonClient("path/to/dbconfig.xml", loggerFactory, "DBCommon");
        
        // 方法3:将Microsoft ILoggerFactory设置为全局默认日志工厂
        DbCommonClient.UseMicrosoftLoggerFactory(loggerFactory);
        _dbClient = new DbCommonClient("path/to/dbconfig.xml");
    }
}

// 直接使用方式
using Microsoft.Extensions.Logging;

// 创建LoggerFactory
var loggerFactory = LoggerFactory.Create(builder => 
{
    builder.AddConsole();
    builder.AddDebug();
});

// 使用Microsoft ILogger
var logger = loggerFactory.CreateLogger("DBCommon");
var dbClient = new DbCommonClient("path/to/dbconfig.xml", logger);

// 使用Microsoft ILoggerFactory
var dbClient2 = new DbCommonClient("path/to/dbconfig.xml", loggerFactory);

// 创建适配器
var loggerAdapter = DbCommonClient.CreateMicrosoftLoggerAdapter(logger);
var factoryAdapter = DbCommonClient.CreateMicrosoftLoggerFactoryAdapter(loggerFactory);

// 设置为默认日志
DbCommonClient.SetDefaultLogger(logger);

// 注册指定名称的日志
DbCommonClient.RegisterLogger("SQLLogger", logger);

// 将Microsoft ILoggerFactory设置为全局默认日志工厂
DbCommonClient.UseMicrosoftLoggerFactory(loggerFactory);

实体生成

// 生成所有表的实体类
var generator = new EntityGenerator(client.GetDbContext());
generator.GenerateEntities("Output/Entities");

// 生成指定表的实体类
generator.GenerateEntity("Output/Entities", "User");

高级用法

Lambda表达式查询

// 复杂条件查询
var users = await db.GetListAsync<User>(it => 
    it.Age > 20 && 
    it.Status == 1 && 
    it.Name.Contains("张")
);

// 排序
var orderedUsers = await db.GetListAsync<User>(
    it => it.Status == 1,
    it => it.Age, 
    OrderByType.Desc
);

// 指定返回字段
var partialUsers = await db.GetListAsync<User>(
    it => it.Status == 1,
    it => new { it.Id, it.Name }
);

多表查询

// 多表连接查询
var query = await db.Queryable<User>()
    .LeftJoin<UserRole>((u, ur) => u.Id == ur.UserId)
    .LeftJoin<Role>((u, ur, r) => ur.RoleId == r.Id)
    .Where((u, ur, r) => u.Status == 1)
    .Select((u, ur, r) => new
    {
        UserId = u.Id,
        UserName = u.Name,
        RoleId = r.Id,
        RoleName = r.Name
    })
    .ToListAsync();

新增功能

分页查询

分页查询可以轻松实现分页功能,支持多种方式:

// 基本分页查询(所有记录)
var page1 = await db.GetPagedListAsync<User>(1, 10); // 第1页,每页10条

// 条件分页查询
var page2 = await db.GetPagedListAsync<User>(u => u.Age > 20, 1, 10);

// 条件排序分页查询
var page3 = await db.GetPagedListAsync<User>(
    u => u.Age > 20, 
    u => u.CreateTime, 
    OrderByType.Desc, 
    1, 10);

// 分页结果包含丰富的信息
Console.WriteLine($"当前页:{page1.PageIndex}");
Console.WriteLine($"每页记录数:{page1.PageSize}");
Console.WriteLine($"总记录数:{page1.TotalCount}");
Console.WriteLine($"总页数:{page1.TotalPages}");
Console.WriteLine($"是否有上一页:{page1.HasPreviousPage}");
Console.WriteLine($"是否有下一页:{page1.HasNextPage}");

// 结果遍历
foreach (var item in page1.Items)
{
    Console.WriteLine($"用户ID:{item.Id},姓名:{item.Name}");
}

缓存查询

缓存查询可以提高查询性能,减少数据库访问:

// 从缓存中获取单个实体,如果缓存中不存在则从数据库获取并缓存
var user = db.GetByIdFromCache<User>(1);

// 指定缓存键和过期时间(30分钟)
var user2 = db.GetByIdFromCache<User>(2, "user:2", TimeSpan.FromMinutes(30));

// 从缓存中获取列表
var users = db.GetListFromCache<User>(u => u.Status == 1);

// 从缓存中获取分页数据
var page = db.GetPagedListFromCache<User>(1, 10);

// 移除指定键的缓存
db.RemoveCache("user:2");

// 移除指定前缀的所有缓存
int count = db.RemoveCacheByPrefix("user:");

查询构造器

DBCommon提供了灵活的查询构造器,用于构建复杂的查询条件和操作。

// 创建查询构造器
var query = dbClient.Query<User>()
    .Where(u => u.Age > 18)
    .OrderBy(u => u.CreateTime, OrderByType.Desc)
    .Skip(10)
    .Take(20)
    .UseCache("users_cache", TimeSpan.FromMinutes(10));

// 获取结果
var users = query.ToList();

// 异步获取结果
var usersAsync = await query.ToListAsync();

// 获取分页结果
var pagedUsers = query.ToPagedList(1, 20);

// 获取第一条记录
var firstUser = query.First();

// 统计记录数
var count = query.Count();

// 判断是否存在符合条件的记录
var exists = query.Any();

// 表连接查询
var query = dbClient.Query<User>()
    .LeftJoin<UserAddress>((u, a) => u.Id == a.UserId)
    .Where(u => u.Status == 1);

查询构造器扩展方法

QueryBuilderExtensions提供了更多高级查询和转换功能。

// 将查询结果转换为指定类型
var userDtos = dbClient.Query<User>()
    .Where(u => u.Status == 1)
    .ToListAs<User, UserDto>();

// 将查询结果分页并转换为指定类型
var pagedUserDtos = dbClient.Query<User>()
    .Where(u => u.Status == 1)
    .ToPagedListAs<User, UserDto>(1, 20);

// 按条件进行分组统计
var userCountByStatus = dbClient.Query<User>()
    .GroupCount(u => u.Status);

// 执行自定义SQL查询
var customResults = dbClient.Query<User>()
    .SqlQuery<User, CustomResult>("SELECT id, name FROM user WHERE age > @age",
        new SugarParameter("@age", 18));

// 将查询结果转换为字典
var userDict = dbClient.Query<User>()
    .ToDictionary(u => u.Id);

批量操作

批量操作提供更高的性能,特别适合大量数据处理:

// 批量插入
var users = new List<User>();
for (int i = 0; i < 1000; i++)
{
    users.Add(new User { Name = $"用户{i}", Age = 20 + i % 50, Status = 1 });
}
int count = await db.BulkInsertAsync(users);

// 批量更新
users.ForEach(u => u.Status = 2);
await db.BulkUpdateAsync(users);

// 批量更新指定字段
await db.BulkUpdateAsync(users, u => new { u.Status });

// 批量删除
await db.BulkDeleteAsync(users);

// 根据条件批量删除
await db.BulkDeleteAsync<User>(u => u.Status == 0);

// 使用DataTable进行SQL批量复制
DataTable dt = new DataTable();
dt.Columns.Add("Name", typeof(string));
dt.Columns.Add("Age", typeof(int));
dt.Columns.Add("Status", typeof(int));

for (int i = 0; i < 1000; i++)
{
    dt.Rows.Add($"用户{i}", 20 + i % 50, 1);
}

await db.SqlBulkCopyAsync<User>(dt);

高级特性

仓储模式

DBCommon提供了仓储模式的支持,可以更加方便地对数据进行操作。

// 创建仓储
var userRepository = dbClient.GetRepository<User>();

// 查询数据
var user = userRepository.GetById(1);
var users = userRepository.GetAll();
var activeUsers = userRepository.GetList(u => u.Status == 1);

// 分页查询
var pagedResult = userRepository.GetPagedList(1, 10);
var pagedActiveUsers = userRepository.GetPagedList(u => u.Status == 1, 1, 10);
var pagedSortedUsers = userRepository.GetPagedList(u => u.Status == 1, u => u.CreateTime, OrderByType.Desc, 1, 10);

// 新增数据
var newUser = new User { Name = "张三", Age = 25 };
userRepository.Insert(newUser);

// 更新数据
user.Age = 26;
userRepository.Update(user);

// 删除数据
userRepository.Delete(user);
userRepository.DeleteById(2);
userRepository.DeleteByCondition(u => u.Status == 0);

// 批量操作
var users = new List<User>();
for (int i = 0; i < 1000; i++)
{
    users.Add(new User { Name = $"用户{i}", Age = 20 + i % 10 });
}
userRepository.BulkInsert(users);

仓储扩展方法

DBCommon提供了丰富的仓储扩展方法,进一步简化数据操作。

// 获取仓储
var userRepository = dbClient.GetRepository<User>();

// 使用SQL查询
var users = userRepository.FromSql("SELECT * FROM users WHERE age > @age", new SugarParameter("@age", 18));

// 执行SQL命令
int rows = userRepository.ExecuteSql("UPDATE users SET status = @status WHERE age < @age",
    new SugarParameter("@status", 0),
    new SugarParameter("@age", 18));

// 获取指定范围的记录
var users = userRepository.GetRange(10, 20); // 跳过10条,获取20条

// 根据条件更新
userRepository.UpdateWhere(
    u => new User { Status = 1, UpdateTime = DateTime.Now },
    u => u.Age > 18 && u.Status == 0
);

// 检查记录是否存在
bool exists = userRepository.Exists(u => u.UserName == "admin");

// 查询并映射到DTO
var userDtos = userRepository.GetListAs<User, UserDto>(u => u.Status == 1);

// 分页查询并映射到DTO
var pagedResult = userRepository.GetPagedListAs<User, UserDto>(1, 10, u => u.Status == 1);

工作单元模式

工作单元模式可以更好地管理数据库操作和事务。

// 创建工作单元
using (var unitOfWork = dbClient.CreateUnitOfWork())
{
    // 获取仓储
    var userRepository = unitOfWork.GetRepository<User>();
    var orderRepository = unitOfWork.GetRepository<Order>();

    // 开始事务
    unitOfWork.BeginTransaction();

    try
    {
        // 执行操作
        var user = userRepository.GetById(1);
        user.Balance -= 100;
        userRepository.Update(user);

        var order = new Order
        {
            UserId = user.Id,
            Amount = 100,
            Status = 1
        };
        orderRepository.Insert(order);

        // 提交事务
        unitOfWork.CommitTransaction();
    }
    catch
    {
        // 回滚事务
        unitOfWork.RollbackTransaction();
        throw;
    }
}

// 使用更简便的方式执行事务
dbClient.UseTransaction(unitOfWork =>
{
    var userRepository = unitOfWork.GetRepository<User>();
    var orderRepository = unitOfWork.GetRepository<Order>();

    var user = userRepository.GetById(1);
    user.Balance -= 100;
    userRepository.Update(user);

    var order = new Order
    {
        UserId = user.Id,
        Amount = 100,
        Status = 1
    };
    orderRepository.Insert(order);
});

// 异步方式执行事务
await dbClient.UseTransactionAsync(async unitOfWork =>
{
    var userRepository = unitOfWork.GetRepository<User>();
    var orderRepository = unitOfWork.GetRepository<Order>();

    var user = await userRepository.GetByIdAsync(1);
    user.Balance -= 100;
    await userRepository.UpdateAsync(user);

    var order = new Order
    {
        UserId = user.Id,
        Amount = 100,
        Status = 1
    };
    await orderRepository.InsertAsync(order);
});

工作单元扩展方法

通过工作单元扩展方法,可以更灵活地进行数据库操作和事务管理。

// 创建工作单元
using (var unitOfWork = dbClient.CreateUnitOfWork())
{
    // 使用WithTransaction方法自动管理事务
    unitOfWork.WithTransaction(() =>
    {
        // 获取仓储
        var userRepository = unitOfWork.GetRepository<User>();
        var orderRepository = unitOfWork.GetRepository<Order>();

        // 执行业务逻辑
        var user = userRepository.GetById(1);
        user.Balance -= 100;
        userRepository.Update(user);

        var order = new Order
        {
            UserId = user.Id,
            Amount = 100,
            Status = 1
        };
        orderRepository.Insert(order);
    });

    // 执行SQL查询
    var users = unitOfWork.SqlQuery<User>("SELECT * FROM users WHERE balance > @balance",
        new SugarParameter("@balance", 1000));

    // 检查表是否存在
    bool tableExists = unitOfWork.TableExists<User>();

    // 创建表
    unitOfWork.CreateTable<User>();

    // 获取数据库时间
    DateTime dbTime = unitOfWork.GetDate();
}

// 异步使用工作单元和事务
await dbClient.UseTransactionAsync(async unitOfWork =>
{
    var userRepository = unitOfWork.GetRepository<User>();
    await userRepository.UpdateColumnsAsync(user, u => new { u.Status, u.UpdateTime });

    // 执行存储过程
    var result = await unitOfWork.ExecuteProcedureAsync<ProcResult>("sp_process_order",
        new SugarParameter("@orderId", 1001));
});

连接字符串构建器

DBCommon提供了连接字符串构建器,使得创建和管理数据库连接字符串变得更加简单。

// 创建MySQL连接字符串构建器
var builder = dbClient.CreateMySqlConnectionStringBuilder();

// 设置连接参数
builder.WithServer("localhost")
       .WithPort(3306)
       .WithDatabase("mydb")
       .WithUsername("root")
       .WithPassword("password")
       .WithMaxPoolSize(100)
       .WithParameter("AllowUserVariables", "True");

// 构建连接字符串
string connectionString = builder.Build();

// 可以直接创建配置并保存
dbClient.SaveConnectionConfig("MyConnection", builder);

// 或者直接保存连接字符串
dbClient.SaveConnectionConfig("MyConnection", connectionString, DBCommon.Enums.DbType.MySql);

许可证

MIT

资源释放

所有关键对象都实现了IDisposable接口,建议使用using语句确保资源正确释放:

// 使用DbCommonClient
using (var client = new DbCommonClient())
{
    // 使用DbContext
    using (var db = client.GetDbContext())
    {
        // 执行数据库操作
        var users = db.GetList<User>();
    }
}

// 或者在ASP.NET Core中注册为单例,由框架自动管理生命周期
services.AddSingleton<DbCommonClient>();

线程安全

组件内部实现了线程安全机制,可安全地在多线程环境下使用:

// 多线程环境中安全使用
var client = new DbCommonClient();

Parallel.For(0, 10, i =>
{
    using (var db = client.GetDbContext())
    {
        // 线程安全的数据库操作
        var user = new User { Name = $"用户{i}", Age = 20 + i };
        db.Insert(user);
    }
});

// 线程安全的配置管理
Parallel.For(0, 5, i =>
{
    var config = new DbConnectionConfig
    {
        Name = $"db{i}",
        DbType = Enums.DbType.MySql,
        ConnectionString = $"server=localhost;database=db{i};uid=root;pwd=123456;charset=utf8;",
        IsMaster = i == 0,
        Enabled = true
    };
    
    client.SaveConfig(config);
});

ASP.NET Core 集成

在ASP.NET Core项目中,可以通过依赖注入来使用DBCommon。

// 在Startup.cs中注册服务
public void ConfigureServices(IServiceCollection services)
{
    // 注册DBCommon服务
    services.AddDBCommon();
    
    // 或者注册DBCommon服务和工作单元
    services.AddDBCommonWithUnitOfWork();
    
    // 注册实体仓储
    services.AddRepository<User>();
    services.AddRepository<Order>();
}

// 在Controller或Service中使用
public class UserService
{
    private readonly DbCommonClient _dbClient;
    private readonly Repository<User> _userRepository;
    private readonly UnitOfWork _unitOfWork;

    public UserService(DbCommonClient dbClient, Repository<User> userRepository, UnitOfWork unitOfWork)
    {
        _dbClient = dbClient;
        _userRepository = userRepository;
        _unitOfWork = unitOfWork;
    }

    public async Task<User> GetUserAsync(int id)
    {
        return await _userRepository.GetByIdAsync(id);
    }

    public async Task CreateOrderAsync(int userId, decimal amount)
    {
        await _unitOfWork.ExecuteInTransactionAsync(async () =>
        {
            var userRepository = _unitOfWork.GetRepository<User>();
            var orderRepository = _unitOfWork.GetRepository<Order>();

            var user = await userRepository.GetByIdAsync(userId);
            user.Balance -= amount;
            await userRepository.UpdateAsync(user);

            var order = new Order
            {
                UserId = userId,
                Amount = amount,
                Status = 1
            };
            await orderRepository.InsertAsync(order);
        });
    }
} 
Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.0.0 439 7 days ago