Acme.EFCore.Small 2.0.0.4-alpha

This is a prerelease version of Acme.EFCore.Small.
There is a newer version of this package available.
See the version list below for details.
dotnet add package Acme.EFCore.Small --version 2.0.0.4-alpha
                    
NuGet\Install-Package Acme.EFCore.Small -Version 2.0.0.4-alpha
                    
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="Acme.EFCore.Small" Version="2.0.0.4-alpha" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Acme.EFCore.Small" Version="2.0.0.4-alpha" />
                    
Directory.Packages.props
<PackageReference Include="Acme.EFCore.Small" />
                    
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 Acme.EFCore.Small --version 2.0.0.4-alpha
                    
#r "nuget: Acme.EFCore.Small, 2.0.0.4-alpha"
                    
#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.
#:package Acme.EFCore.Small@2.0.0.4-alpha
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Acme.EFCore.Small&version=2.0.0.4-alpha&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=Acme.EFCore.Small&version=2.0.0.4-alpha&prerelease
                    
Install as a Cake Tool

Acme.EFCore.Small

1、项目概述

Acme.EFCore.Small 是一个轻量级的 Entity Framework Core 通用库,用于使用 Entity Framework Core (EFCore) 与数据库进行交互。它是处理各种数据库操作的基础组件。

  • 版本:v2.0.0.10
  • 作者:yzxs
  • 描述:轻量级 EFCore 操作类库
  • 发布说明:
    • 1.更新.NET 10.0 版本的EFCore依赖包为10.0.10
    • 2.修复已知bug……

2、入门指南

2.1. 安装 Acme.EFCore.Small

创建项目 → 点击引用 → 右键 → 管理 NuGet 包 → 搜索 Acme.EFCore.Small 并选择 2.0.0.2-alpha 或更高版本。根据您的 .NET 框架安装适当的版本。

2.2. 安装对应的数据库包

  • SqlServer: Microsoft.EntityFrameworkCore.SqlServer
  • Sqlite: Microsoft.EntityFrameworkCore.Sqlite
  • Cosmos: Microsoft.EntityFrameworkCore.Cosmos
  • InMemoryDatabase: Microsoft.EntityFrameworkCore.InMemory
  • MySql:
    • Pomelo.EntityFrameworkCore.MySql
    • MySql.EntityFrameworkCore
  • PostgreSQL: Npgsql.EntityFrameworkCore.PostgreSQL
  • Oracle: Oracle.EntityFrameworkCore
  • Firebird: FirebirdSql.EntityFrameworkCore.Firebird
  • Dm: Microsoft.EntityFrameworkCore.Dm

2.3. 创建数据库上下文类

// 主数据库上下文
public class AppDbContext : DbContext
{
    /// <summary>
    /// 初始化数据库上下文
    /// </summary>
    /// <param name="options"></param>
    public AppDbContext(DbContextOptions<AppDbContext> options) :
       base(options)
    {
    }
    
    // 在此添加您的 DbSet 属性
    public DbSet<User> Users { get; set; }
    public DbSet<Product> Products { get; set; }
}

// 多库场景下的第二个数据库上下文
public class OrderDbContext : DbContext
{
    /// <summary>
    /// 初始化数据库上下文
    /// </summary>
    /// <param name="options"></param>
    public OrderDbContext(DbContextOptions<OrderDbContext> options) :
       base(options)
    {
    }
    
    // 在此添加您的 DbSet 属性
    public DbSet<Order> Orders { get; set; }
    public DbSet<OrderItem> OrderItems { get; set; }
}

2.4. 配置连接字符串

{
    "ConnectionStrings":{
        "DefaultConnection": "Persist Security Info=False;Data Source=.;Initial Catalog=数据库名称;User ID=用户名;Password=密码;Connect Timeout=120;Encrypt=False;",
        "OrderConnection": "Persist Security Info=False;Data Source=.;Initial Catalog=订单数据库名称;User ID=用户名;Password=密码;Connect Timeout=120;Encrypt=False;"
    }
}

2.5. 依赖注入

2.5.1. 单库模式配置
// 在 Startup.cs 或 Program.cs 中配置
// 注册数据库上下文
services.AddDbContext<AppDbContext>(options => 
    options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

// 注册单库模式仓储(包含工作单元)
services.AddRepositorys<AppDbContext>();
2.5.2. 多库模式配置
// 在 Startup.cs 或 Program.cs 中配置
// 注册第一个数据库上下文
services.AddDbContext<AppDbContext>(options => 
    options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

// 注册第二个数据库上下文
services.AddDbContext<OrderDbContext>(options => 
    options.UseSqlServer(Configuration.GetConnectionString("OrderConnection")));

// 注册多库模式仓储(包含工作单元)
services.AddRepositorys();

3、核心功能

3.1. 基础类

3.1.1. 实体基础类

BaseEntity 提供了基本的实体属性,适用于大多数实体类型。

// 继承 BaseEntity 以获取基本实体属性
public class User : BaseEntity
{
    public string Name { get; set; }
    public string Email { get; set; }
    public string Phone { get; set; }
    public DateTime BirthDate { get; set; }
    public bool IsActive { get; set; }
}
3.1.2. 聚合根基础类

BaseAggregateRoot 适用于作为聚合根的实体,通常包含子实体集合。

// 继承 BaseAggregateRoot 用于聚合根实体
public class Order : BaseAggregateRoot
{
    public string OrderNumber { get; set; }
    public DateTime OrderDate { get; set; }
    public decimal TotalAmount { get; set; }
    public string Status { get; set; }
    public List<OrderItem> Items { get; set; } = new List<OrderItem>();
}

// 子实体
public class OrderItem : BaseEntity
{
    public int OrderId { get; set; }
    public int ProductId { get; set; }
    public string ProductName { get; set; }
    public decimal UnitPrice { get; set; }
    public int Quantity { get; set; }
    public decimal Subtotal { get; set; }
}
3.1.3. 值对象基础类

BaseValueObject 适用于值对象,通常用于表示没有唯一标识的概念。

// 继承 BaseValueObject 用于值对象
public class Address : BaseValueObject
{
    public string Street { get; set; }
    public string City { get; set; }
    public string Province { get; set; }
    public string Country { get; set; }
    public string ZipCode { get; set; }
}

// 在实体中使用值对象
public class User : BaseEntity
{
    public string Name { get; set; }
    public Address HomeAddress { get; set; }
    public Address WorkAddress { get; set; }
}

3.2. 仓储模式

3.2.1. 单库模式

单库模式适用于项目中只使用一个数据库的场景,使用 IRepository<TEntity> 接口。

// 注入单库仓储
private readonly IRepository<User> _userRepository;
private readonly IRepository<Product> _productRepository;

public UserService(IRepository<User> userRepository, IRepository<Product> productRepository)
{
    _userRepository = userRepository;
    _productRepository = productRepository;
}

// 1. 添加新用户
public int AddUser(User user)
{
    return _userRepository.AddNowSave(user);
}

// 2. 根据ID获取用户
public User GetUserById(int id)
{
    return _userRepository.GetInfoById(id);
}

// 3. 根据条件获取用户
public User GetUserByCondition(int id)
{
    return _userRepository.GetInfoDefault(u => u.Id == id);
}

// 4. 更新用户
public bool UpdateUser(User user)
{
    return _userRepository.UpdateNowSave(user);
}

// 5. 删除用户
public bool DeleteUser(User user)
{
    return _userRepository.DeleteNowSave(user);
}

// 6. 获取带条件的用户列表
public List<User> GetUsers(string name)
{
    return _userRepository.GetList(u => u.Name.Contains(name));
}

// 7. 批量添加用户
public int AddUsers(List<User> users)
{
    return _userRepository.AddManyNowSave(users);
}

// 8. 检查用户是否存在
public bool UserExists(string email)
{
    return _userRepository.Any(u => u.Email == email);
}

// 9. 获取用户数量
public int GetUserCount(bool isActive)
{
    return _userRepository.Count(u => u.IsActive == isActive);
}
3.2.2. 多库模式

多库模式适用于项目中使用多个数据库的场景,使用 IRepository<TDbContext, TEntity> 接口,需要指定具体的数据库上下文类型。

// 注入多库仓储
private readonly IRepository<AppDbContext, User> _userRepository;
private readonly IRepository<OrderDbContext, Order> _orderRepository;
private readonly IRepository<OrderDbContext, OrderItem> _orderItemRepository;

public OrderService(IRepository<AppDbContext, User> userRepository, 
                   IRepository<OrderDbContext, Order> orderRepository,
                   IRepository<OrderDbContext, OrderItem> orderItemRepository)
{
    _userRepository = userRepository;
    _orderRepository = orderRepository;
    _orderItemRepository = orderItemRepository;
}

// 从不同数据库获取数据
public async Task<(User, Order)> GetUserAndOrder(int userId, int orderId)
{
    var user = await _userRepository.GetInfoDefaultAsync(u => u.Id == userId);
    var order = await _orderRepository.GetInfoDefaultAsync(o => o.Id == orderId);
    return (user, order);
}

// 在多个数据库之间进行操作
public async Task<bool> CreateOrderWithUser(int userId, Order order)
{
    try
    {
        // 验证用户是否存在
        var userExists = await _userRepository.AnyAsync(u => u.Id == userId);
        if (!userExists)
        {
            return false;
        }
        
        // 创建订单
        await _orderRepository.AddNowSaveAsync(order);
        
        // 创建订单项
        foreach (var item in order.Items)
        {
            item.OrderId = order.Id;
            await _orderItemRepository.AddNowSaveAsync(item);
        }
        
        return true;
    }
    catch (Exception)
    {
        return false;
    }
}
3.2.3. 异步操作
// 异步添加
public async Task<int> AddUserAsync(User user)
{
    return await _userRepository.AddNowSaveAsync(user);
}

// 异步根据ID获取
public async Task<User> GetUserByIdAsync(int id)
{
    return await _userRepository.GetInfoByIdAsync(id);
}

// 异步根据条件获取
public async Task<User> GetUserByConditionAsync(int id)
{
    return await _userRepository.GetInfoDefaultAsync(u => u.Id == id);
}

// 异步批量添加
public async Task<int> AddUsersAsync(List<User> users)
{
    return await _userRepository.AddManyNowSaveAsync(users);
}

// 异步获取列表
public async Task<List<User>> GetUsersAsync(string name)
{
    return await _userRepository.GetListAsync(u => u.Name.Contains(name));
}

// 异步检查是否存在
public async Task<bool> UserExistsAsync(string email)
{
    return await _userRepository.AnyAsync(u => u.Email == email);
}

3.3. 工作单元模式

工作单元模式用于管理事务和提交操作,将数据变更作为一个原子单元进行处理。

3.3.1. 注入工作单元
// 注入工作单元
private readonly IUnitOfWork<OrderDbContext> _unitOfWork;

public OrderService(
    IRepository<OrderDbContext, Order> orderRepository, 
    IRepository<OrderDbContext, OrderItem> orderItemRepository,
    IUnitOfWork<OrderDbContext> unitOfWork)
{
    _orderRepository = orderRepository;
    _orderItemRepository = orderItemRepository;
    _unitOfWork = unitOfWork;
}
3.3.2. 基本事务示例
// 使用事务
public void ProcessOrder(Order order)
{
    try
    {
        // 开始事务
        _unitOfWork.BeginTransaction();
        
        // 执行操作
        _orderRepository.Add(order);
        
        foreach (var item in order.Items)
        {
            _orderItemRepository.Add(item);
        }
        
        // 提交更改
        _unitOfWork.Submit();
        
        // 提交事务
        _unitOfWork.CommitTransaction();
    }
    catch (Exception ex)
    {
        // 出错时回滚事务
        _unitOfWork.RollbackTransaction();
        throw;
    }
}
3.3.3. 异步事务示例
// 异步事务
public async Task<bool> ProcessOrderAsync(Order order)
{
    try
    {
        // 开始事务
        await _unitOfWork.BeginTransactionAsync();
        
        // 执行操作
        await _orderRepository.AddAsync(order);
        
        foreach (var item in order.Items)
        {
            await _orderItemRepository.AddAsync(item);
        }
        
        // 提交更改
        await _unitOfWork.SubmitAsync();
        
        // 提交事务
        await _unitOfWork.CommitTransactionAsync();
        return true;
    }
    catch (Exception ex)
    {
        // 出错时回滚事务
        await _unitOfWork.RollbackTransactionAsync();
        return false;
    }
}

3.4. 分页功能

分页功能用于处理大量数据,提高查询性能和用户体验。

3.4.1. 基本分页
// 使用分页
public PageList<User> GetUsersPaged(int pageIndex, int pageSize, string name)
{
    var query = _userRepository.Queryable(u => u.Name.Contains(name));
    return query.ToPageList(pageIndex, pageSize);
}
3.4.2. 带排序的分页
// 带排序的分页
public PageList<User> GetUsersPagedWithSorting(int pageIndex, int pageSize, string name, Sorting sorting)
{
    var query = _userRepository.Queryable(u => u.Name.Contains(name));
    
    // 使用 AddSorting 扩展方法进行排序
    query = query.AddSorting(sorting);
    
    return query.ToPageList(pageIndex, pageSize);
}
3.4.3. 分页结果使用

PageList<T> 是分页结果的泛型类,包含以下两个属性:

属性 类型 说明
Total int 总记录条数
Items List<T> 当前页的数据集合
// 调用分页方法
var pageResult = userService.GetUsersPaged(1, 10, "张");

// 分页结果使用
int totalCount = pageResult.Total;       // 总记录条数
List<User> items = pageResult.Items;     // 当前页数据集合

// 如需获取其他分页信息,可基于 Total 自行计算
int pageIndex = 1;                       // 当前页码(由调用方传入)
int pageSize = 10;                       // 每页大小(由调用方传入)
int totalPages = (int)Math.Ceiling((double)totalCount / pageSize);  // 总页数
bool hasNextPage = pageIndex < totalPages;   // 是否有下一页
bool hasPrevPage = pageIndex > 1;            // 是否有上一页

4、高级功能

4.1. 查询扩展

4.1.1. WhereIf 条件过滤

WhereIf 扩展方法用于根据布尔条件动态决定是否添加查询条件,简化条件判断逻辑。

// 使用 WhereIf 简化动态条件
public List<User> GetUsersWithConditions(string name, int? age, bool? isActive)
{
    var query = _userRepository.Queryable();
    
    // WhereIf:第一个参数为 true 时,才应用 lambda 条件
    query = query.WhereIf(!string.IsNullOrEmpty(name), u => u.Name.Contains(name));
    query = query.WhereIf(age.HasValue, u => u.Age == age.Value);
    query = query.WhereIf(isActive.HasValue, u => u.IsActive == isActive.Value);
    
    return query.ToList();
}
4.1.2. 动态排序

使用 AddSorting 扩展方法进行动态排序,传入 Sorting 对象指定排序字段和排序类型。

// 使用 AddSorting 扩展方法进行动态排序
public List<User> GetUsersWithDynamicSorting(string name, Sorting sorting)
{
    var query = _userRepository.Queryable(u => u.Name.Contains(name));
    
    // 使用 AddSorting 扩展方法,传入 Sorting 对象
    query = query.AddSorting(sorting);
    
    return query.ToList();
}

Sorting 类属性:

属性 类型 说明
SortField string 排序字段名
SortingType SortingType 排序类型(ASC 正序 / DESC 倒序)

也支持条件判断是否排序:

// 根据条件决定是否排序
query = query.AddSortingIf(needSort, sorting);
4.1.3. Condition 条件查询

Condition 类配合 AddConditions 扩展方法,支持以列表形式动态构建复杂查询条件,支持多种运算符。

// 使用 Condition 列表构建查询条件
public List<User> GetUsersByConditions(List<Condition> conditions)
{
    var query = _userRepository.Queryable();
    
    // 批量应用查询条件
    query = query.AddConditions(conditions);
    
    return query.ToList();
}

// 构建条件列表示例
var conditions = new List<Condition>
{
    new Condition("Name", "张", Symbol.Contains),
    new Condition("Age", "18", Symbol.GreaterThanOrEqual),
    new Condition("IsActive", "true", Symbol.Equal)
};

Condition 类属性:

属性 类型 说明
Field string 字段名
Value string 字段值
Symbol Symbol 运算符

Symbol 枚举支持的运算符:

运算符 值 说明
Equal 0 等于
NotEqual 1 不等于
GreaterThan 2 大于
LessThan 3 小于
GreaterThanOrEqual 4 大于等于
LessThanOrEqual 5 小于等于
Contains 6 模糊包含
NotContains 7 不包含
StartsWith 8 开头匹配
EndsWith 9 结尾匹配
In 10 包含于列表
NotIn 11 不包含于列表
IsNull 12 为 NULL
IsNotNull 13 不为 NULL

也支持条件判断是否应用:

query = query.AddConditionsIf(isFilter, conditions);
4.1.4. Keywords 关键字模糊查询

Keywords 类配合 AddConditionsContains 扩展方法,支持在多个字段中同时进行模糊搜索。

// 使用 Keywords 进行多字段模糊查询
public List<User> GetUsersByKeywords(Keywords keywords)
{
    var query = _userRepository.Queryable();
    
    // 在多个字段中模糊匹配关键字
    query = query.AddConditionsContains(keywords);
    
    return query.ToList();
}

// 使用示例:在 Name 和 Email 字段中搜索关键字 "张"
var keywords = new Keywords(new[] { "Name", "Email" }, "张");
var users = userService.GetUsersByKeywords(keywords);

Keywords 类属性:

属性 类型 说明
Fields string[] 要搜索的字段名称数组
Value string 搜索的关键字值

也支持条件判断是否应用:

query = query.AddConditionsContains(isSearch, keywords);

4.2. 无跟踪查询

无跟踪查询适用于只读操作,可以提高查询性能。

// 使用无跟踪查询进行只读操作
public List<User> GetUsersReadOnly()
{
    return _userRepository.GetListNoTracking();
}

// 带条件的无跟踪查询
public User GetUserByIdReadOnly(int id)
{
    return _userRepository.GetInfoNoTracking(u => u.Id == id);
}

// 异步无跟踪查询
public async Task<List<User>> GetUsersReadOnlyAsync(string name)
{
    var query = _userRepository.Queryable(u => u.Name.Contains(name));
    return await query.AsNoTracking().ToListAsync();
}

4.3. 批量操作

4.3.1. 批量删除
// 批量删除
public bool DeleteInactiveUsers()
{
    var inactiveUsers = _userRepository.GetList(u => !u.IsActive);
    if (inactiveUsers.Count == 0)
    {
        return true;
    }
    return _userRepository.DelManyNowSave(inactiveUsers);
}

// 异步批量删除
public async Task<bool> DeleteInactiveUsersAsync()
{
    var inactiveUsers = await _userRepository.GetListAsync(u => !u.IsActive);
    if (inactiveUsers.Count == 0)
    {
        return true;
    }
    return await _userRepository.DelManyNowSaveAsync(inactiveUsers);
}
4.3.2. 批量更新
// 批量更新
public bool UpdateUserStatus(bool isActive, List<int> userIds)
{
    var users = _userRepository.GetList(u => userIds.Contains(u.Id));
    foreach (var user in users)
    {
        user.IsActive = isActive;
    }
    return _userRepository.UpdateManyNowSave(users);
}

// 异步批量更新
public async Task<bool> UpdateUserStatusAsync(bool isActive, List<int> userIds)
{
    var users = await _userRepository.GetListAsync(u => userIds.Contains(u.Id));
    foreach (var user in users)
    {
        user.IsActive = isActive;
    }
    return await _userRepository.UpdateManyNowSaveAsync(users);
}

5、完整使用案例

5.1. 单库模式完整示例

5.1.1. 实体定义
// 用户实体
public class User : BaseEntity
{
    public string Name { get; set; }
    public string Email { get; set; }
    public string Phone { get; set; }
    public bool IsActive { get; set; }
}

// 产品实体
public class Product : BaseEntity
{
    public string Name { get; set; }
    public decimal Price { get; set; }
    public int Stock { get; set; }
    public bool IsAvailable { get; set; }
}
5.1.2. 数据库上下文
public class AppDbContext : DbContext
{
    public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
    {}
    
    public DbSet<User> Users { get; set; }
    public DbSet<Product> Products { get; set; }
}
5.1.3. 服务层
public class UserService
{
    private readonly IRepository<User> _userRepository;
    private readonly IUnitOfWork _unitOfWork;
    
    public UserService(IRepository<User> userRepository, IUnitOfWork unitOfWork)
    {
        _userRepository = userRepository;
        _unitOfWork = unitOfWork;
    }
    
    // 创建用户
    public async Task<int> CreateUserAsync(User user)
    {
        // 检查邮箱是否已存在
        if (await _userRepository.AnyAsync(u => u.Email == user.Email))
        {
            throw new Exception("邮箱已被注册");
        }
        
        return await _userRepository.AddNowSaveAsync(user);
    }
    
    // 获取用户列表
    public async Task<PageList<User>> GetUsersAsync(int pageIndex, int pageSize, string name = null)
    {
        var query = _userRepository.Queryable();
        
        if (!string.IsNullOrEmpty(name))
        {
            query = query.Where(u => u.Name.Contains(name));
        }
        
        return await query.ToPageListAsync(pageIndex, pageSize);
    }
    
    // 更新用户信息
    public async Task<bool> UpdateUserAsync(User user)
    {
        // 检查用户是否存在
        var existingUser = await _userRepository.GetInfoDefaultAsync(u => u.Id == user.Id);
        if (existingUser == null)
        {
            return false;
        }
        
        // 检查邮箱是否被其他用户使用
        if (await _userRepository.AnyAsync(u => u.Email == user.Email && u.Id != user.Id))
        {
            throw new Exception("邮箱已被其他用户使用");
        }
        
        return await _userRepository.UpdateSaveAsync(user);
    }
    
    // 删除用户
    public async Task<bool> DeleteUserAsync(int userId)
    {
        var user = await _userRepository.GetInfoDefaultAsync(u => u.Id == userId);
        if (user == null)
        {
            return false;
        }
        
        return await _userRepository.DeleteNowSaveAsync(user);
    }
}
5.1.4. 控制器
[ApiController]
[Route("api/[controller]")]
public class UserController : ControllerBase
{
    private readonly UserService _userService;
    
    public UserController(UserService userService)
    {
        _userService = userService;
    }
    
    [HttpPost]
    public async Task<IActionResult> Create(User user)
    {
        try
        {
            var result = await _userService.CreateUserAsync(user);
            if (result > 0)
            {
                return CreatedAtAction(nameof(Get), new { id = user.Id }, user);
            }
            return BadRequest("创建失败");
        }
        catch (Exception ex)
        {
            return BadRequest(ex.Message);
        }
    }
    
    [HttpGet("{id}")]
    public async Task<IActionResult> Get(int id)
    {
        var user = await _userRepository.GetInfoByIdAsync(id);
        if (user == null)
        {
            return NotFound();
        }
        return Ok(user);
    }
    
    [HttpGet]
    public async Task<IActionResult> GetList([FromQuery] int pageIndex = 1, [FromQuery] int pageSize = 10, [FromQuery] string name = null)
    {
        var users = await _userService.GetUsersAsync(pageIndex, pageSize, name);
        return Ok(users);
    }
    
    [HttpPut]
    public async Task<IActionResult> Update(User user)
    {
        try
        {
            var result = await _userService.UpdateUserAsync(user);
            if (!result)
            {
                return NotFound();
            }
            return Ok();
        }
        catch (Exception ex)
        {
            return BadRequest(ex.Message);
        }
    }
    
    [HttpDelete("{id}")]
    public async Task<IActionResult> Delete(int id)
    {
        var result = await _userService.DeleteUserAsync(id);
        if (!result)
        {
            return NotFound();
        }
        return Ok();
    }
}

5.2. 多库模式完整示例

5.2.1. 数据库上下文
// 主数据库上下文
public class AppDbContext : DbContext
{
    public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
    {}
    
    public DbSet<User> Users { get; set; }
    public DbSet<Role> Roles { get; set; }
}

// 订单数据库上下文
public class OrderDbContext : DbContext
{
    public OrderDbContext(DbContextOptions<OrderDbContext> options) : base(options)
    {}
    
    public DbSet<Order> Orders { get; set; }
    public DbSet<OrderItem> OrderItems { get; set; }
}
5.2.2. 服务层
public class OrderService
{
    private readonly IRepository<AppDbContext, User> _userRepository;
    private readonly IRepository<OrderDbContext, Order> _orderRepository;
    private readonly IRepository<OrderDbContext, OrderItem> _orderItemRepository;
    private readonly IUnitOfWork<OrderDbContext> _unitOfWork;
    
    public OrderService(
        IRepository<AppDbContext, User> userRepository,
        IRepository<OrderDbContext, Order> orderRepository,
        IRepository<OrderDbContext, OrderItem> orderItemRepository,
        IUnitOfWork<OrderDbContext> unitOfWork)
    {
        _userRepository = userRepository;
        _orderRepository = orderRepository;
        _orderItemRepository = orderItemRepository;
        _unitOfWork = unitOfWork;
    }
    
    // 创建订单
    public async Task<Order> CreateOrderAsync(int userId, List<OrderItemDto> items)
    {
        // 验证用户是否存在
        var user = await _userRepository.GetInfoDefaultAsync(u => u.Id == userId);
        if (user == null)
        {
            throw new Exception("用户不存在");
        }
        
        // 创建订单
        var order = new Order
        {
            UserId = userId,
            OrderDate = DateTime.Now,
            Status = "待处理",
            TotalAmount = items.Sum(item => item.Quantity * item.UnitPrice)
        };
        
        // 开始事务
        await _unitOfWork.BeginTransactionAsync();
        
        try
        {
            // 保存订单
            await _orderRepository.AddAsync(order);
            await _unitOfWork.SubmitAsync();
            
            // 保存订单项
            foreach (var itemDto in items)
            {
                var item = new OrderItem
                {
                    OrderId = order.Id,
                    ProductId = itemDto.ProductId,
                    ProductName = itemDto.ProductName,
                    UnitPrice = itemDto.UnitPrice,
                    Quantity = itemDto.Quantity,
                    Subtotal = itemDto.Quantity * itemDto.UnitPrice
                };
                await _orderItemRepository.AddAsync(item);
            }
            
            await _unitOfWork.SubmitAsync();
            await _unitOfWork.CommitTransactionAsync();
            
            return order;
        }
        catch (Exception ex)
        {
            await _unitOfWork.RollbackTransactionAsync();
            throw new Exception("创建订单失败:" + ex.Message);
        }
    }
    
    // 获取用户的订单列表
    public async Task<List<Order>> GetUserOrdersAsync(int userId)
    {
        // 验证用户是否存在
        var userExists = await _userRepository.AnyAsync(u => u.Id == userId);
        if (!userExists)
        {
            throw new Exception("用户不存在");
        }
        
        // 获取用户订单
        return await _orderRepository.GetListAsync(o => o.UserId == userId);
    }
    
    // 获取订单详情
    public async Task<Order> GetOrderDetailsAsync(int orderId)
    {
        var order = await _orderRepository.GetInfoDefaultAsync(o => o.Id == orderId);
        if (order == null)
        {
            throw new Exception("订单不存在");
        }
        
        // 获取订单项
        order.Items = await _orderItemRepository.GetListAsync(item => item.OrderId == orderId);
        
        return order;
    }
}

6、支持的 .NET 版本

  • netcoreapp3.1
  • net5
  • net6
  • net7
  • net8
  • net9
  • net10.0

7、NuGet 包信息

8、测试

项目包含完整的测试套件,覆盖所有核心功能:

  • EntityTests: 测试 BaseEntity 和 BaseAggregateRoot 类
  • ValueObjectTests: 测试 BaseValueObject 类
  • PageListTests: 测试 PageList 类
  • PageListExtensionTests: 测试 PageListExtension 类
  • QueryTests: 测试 Condition、Keywords 和 Sorting 类
  • LinqExtensionTests: 测试 LinqExtension 类的关键方法
  • RepositoryTests: 测试 IRepository 接口的结构
  • UnitOfWorkTests: 测试 UnitOfWork 类和 IUnitOfWork 接口

运行测试:

dotnet test Acme.EFCore.Small.Tests\Acme.EFCore.Small.Tests.csproj

9、联系

如有任何问题或问题,请联系作者

Product Compatible and additional computed target framework versions.
.NET net5.0 is compatible.  net5.0-windows was computed.  net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 is compatible.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  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 is compatible.  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.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp3.1 is compatible. 
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
2.0.0.6 105 9/9/2026
2.0.0.5 97 8/28/2026
2.0.0.4 116 8/24/2026
2.0.0.4-alpha 105 7/16/2026
2.0.0.3 111 7/27/2026
2.0.0.3-alpha 110 5/24/2026
2.0.0.2 115 7/27/2026
2.0.0.2-alpha 115 4/21/2026
2.0.0.1 128 7/16/2026
2.0.0.1-alpha 136 3/26/2026
1.3.7.1 108 7/27/2026
1.3.7 129 5/24/2026
1.3.6.9 122 5/24/2026
1.3.6.8 126 4/21/2026
1.3.6.7 127 3/25/2026
1.3.6.6 136 3/16/2026
1.3.6.5 134 3/16/2026
1.3.6.4 143 2/26/2026
1.3.6.3 172 1/14/2026
1.3.6.2 308 12/19/2025
Loading failed

1.更新.NET 10.0 版本的EFCore依赖包为10.0.10
2.修复已知bug……