You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在C# WebCore Entity Framework中如何获取其他实体?

嘿,我刚好做过类似的文件缓存转正的场景,给你梳理下具体的实现方案和代码示例,应该能帮到你:

核心思路

先明确整个流程的核心逻辑:用户上传文件后暂存到FileCacheContext作为缓存,待用户确认操作后,将缓存文件的元数据(甚至文件内容)迁移到正式的业务数据库表中,同时清理缓存记录(或标记为已迁移)。关键要保证迁移过程的原子性,避免数据不一致。

具体实现步骤

1. 实体定义

首先确保缓存表和正式业务表的实体有对应的属性,方便后续映射:

// 缓存表实体 - 存储暂存的文件信息
public class FileCache
{
    public Guid Id { get; set; }
    public string FileName { get; set; }
    public string FileHash { get; set; } // 用于校验文件完整性,上传时生成
    public long ContentLength { get; set; }
    public byte[] FileContent { get; set; } // 如果是小文件可以存数据库,大文件建议存路径
    public Guid UploaderUserId { get; set; } // 记录上传用户,用于权限校验
    public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
}

// 正式业务表实体 - 存储用户确认后的文件
public class UserUploadedFile
{
    public Guid Id { get; set; }
    public string FileName { get; set; }
    public string FileHash { get; set; }
    public long ContentLength { get; set; }
    public byte[] FileContent { get; set; }
    public Guid UserId { get; set; }
    public DateTime ConfirmedAt { get; set; } = DateTime.UtcNow;
    // 可以添加更多业务相关字段,比如关联的业务ID等
}

2. 确保上下文注入正确

你已经在启动时注入了FileCacheContext,记得把正式业务的上下文也注册进去(如果还没的话):

// Program.cs
builder.Services.AddDbContext<FileCacheContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("FileCacheConn")));

builder.Services.AddDbContext<AppDbContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("AppMainConn")));

3. 实现文件升级的API接口

写一个REST接口,处理用户的确认请求,这里要注意用事务保证操作的原子性:

[ApiController]
[Route("api/file-operations")]
public class FileOperationController : ControllerBase
{
    private readonly FileCacheContext _cacheDb;
    private readonly AppDbContext _mainDb;

    public FileOperationController(FileCacheContext cacheDb, AppDbContext mainDb)
    {
        _cacheDb = cacheDb;
        _mainDb = mainDb;
    }

    [HttpPost("upgrade/{cacheFileId:guid}")]
    public async Task<IActionResult> UpgradeCachedFile(Guid cacheFileId)
    {
        // 先获取当前用户ID(根据你的身份验证方式调整,比如JWT)
        var currentUserId = User.FindFirstValue(ClaimTypes.NameIdentifier);
        if (string.IsNullOrEmpty(currentUserId))
        {
            return Unauthorized("请先登录");
        }

        // 1. 查询缓存文件,同时校验权限
        var cachedFile = await _cacheDb.FileCaches
            .FirstOrDefaultAsync(f => f.Id == cacheFileId && f.UploaderUserId == Guid.Parse(currentUserId));
        
        if (cachedFile == null)
        {
            return NotFound("缓存文件不存在或您无权限操作");
        }

        // 2. 开启事务(如果两个上下文用的是同一个数据库,用单个事务即可;不同库则用分布式事务)
        using var transaction = await _mainDb.Database.BeginTransactionAsync();
        try
        {
            // 3. 映射缓存文件到正式实体
            var officialFile = new UserUploadedFile
            {
                Id = Guid.NewGuid(),
                FileName = cachedFile.FileName,
                FileHash = cachedFile.FileHash,
                ContentLength = cachedFile.ContentLength,
                FileContent = cachedFile.FileContent,
                UserId = Guid.Parse(currentUserId)
            };

            // 4. 添加到正式数据库
            _mainDb.UserUploadedFiles.Add(officialFile);
            await _mainDb.SaveChangesAsync();

            // 5. 清理缓存(或者标记为已迁移,根据需求保留历史)
            _cacheDb.FileCaches.Remove(cachedFile);
            await _cacheDb.SaveChangesAsync();

            // 6. 提交事务
            await transaction.CommitAsync();

            // 返回正式文件信息给前端
            return Ok(new
            {
                FileId = officialFile.Id,
                officialFile.FileName,
                officialFile.ConfirmedAt,
                Message = "文件已成功升级"
            });
        }
        catch (Exception ex)
        {
            // 出错回滚事务
            await transaction.RollbackAsync();
            return StatusCode(500, $"文件升级失败:{ex.Message}");
        }
    }
}
关键注意事项
  • 事务处理:如果缓存库和业务库是同一个数据库,直接用单个上下文的事务就行;如果是不同数据库,需要启用EF Core的分布式事务支持(比如依赖Microsoft.EntityFrameworkCore.SqlServer的分布式事务功能)。
  • 大文件优化:如果上传的是大文件,不要把文件内容存在数据库里,建议存储到本地磁盘或云存储,数据库只存文件路径和元数据,迁移时只需要复制路径或者修改标记,性能会好很多。
  • 缓存清理:要定时清理未被确认的缓存文件,避免数据库膨胀。可以用ASP.NET Core的HostedService写一个后台任务,定期删除创建时间超过N小时的缓存记录。
  • 完整性校验:迁移时可以重新计算文件的Hash值,和缓存中的Hash对比,确保文件在缓存期间没有被篡改。
  • 权限控制:一定要校验用户是否有权限操作对应的缓存文件,避免越权操作。

内容的提问来源于stack exchange,提问作者antonye

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 04:17:19