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

如何获取Entity Framework Core批量插入数据的自动生成ID?

问题(翻译后)

我正在使用Entity Framework Core的AddRange方法批量向数据库插入多条数据。目前我能想到的获取这些数据ID列自动生成ID的方法只有循环遍历实体并逐个查询,这看起来效率极低,我肯定遗漏了什么方法。请问获取所有新ID的正确方式是什么?我的插入代码如下:

public async Task<List<int>> UploadFile(Dictionary<IFormFile, string> files, string containerName, string connectionString)
{
    var blobServiceClient = new BlobServiceClient(connectionString);
    var containerClient = blobServiceClient.GetBlobContainerClient(containerName);
    await containerClient.CreateIfNotExistsAsync();
    var fileIDs = new List<int>();
    var filesInfo = new List<SiteFile>();

    foreach (KeyValuePair<IFormFile, string> file in files)
    {
        var fileName = String.Concat(file.Value, ContentTypetoFileExtention.GetValueOrDefault(file.Key.ContentType));
        var blob = containerClient.GetBlobClient(fileName);
        await blob.SetHttpHeadersAsync(new BlobHttpHeaders { ContentType = file.Key.ContentType });

        using (Stream stream = file.Key.OpenReadStream())
        {
            await blob.UploadAsync(stream);
        }

        filesInfo.Add(new SiteFile()
        {
            ContainerName = containerName,
            FileName = fileName
        });
    }

    await _siteDbContext.SiteFiles.AddRangeAsync(filesInfo);
    await _siteDbContext.SaveChangesAsync();

    //Get IDs, somehow?

    return fileIDs;
}

解决方案

直接从你创建的filesInfo集合中提取ID即可,无需额外查询数据库。

当调用SaveChangesAsync()后,EF Core会自动将数据库生成的主键值回填到对应的实体属性中——不管是单个Add还是批量AddRange操作,这个机制都生效。你只需要在SaveChangesAsync()执行完成后,遍历filesInfo集合提取ID:

// 替换注释处的代码
fileIDs = filesInfo.Select(f => f.Id).ToList();

原理说明

对于数据库生成的主键(比如SQL Server的IDENTITY列、MySQL的AUTO_INCREMENT列),EF Core在执行插入操作时,会自动从数据库获取生成的ID值,并赋值给你传入的实体对象的主键属性。这是EF Core内置的功能,完全不需要额外的查询操作,性能和效率都远高于逐个查询。

修改后的完整代码

public async Task<List<int>> UploadFile(Dictionary<IFormFile, string> files, string containerName, string connectionString)
{
    var blobServiceClient = new BlobServiceClient(connectionString);
    var containerClient = blobServiceClient.GetBlobContainerClient(containerName);
    await containerClient.CreateIfNotExistsAsync();
    var fileIDs = new List<int>();
    var filesInfo = new List<SiteFile>();

    foreach (KeyValuePair<IFormFile, string> file in files)
    {
        var fileName = String.Concat(file.Value, ContentTypetoFileExtention.GetValueOrDefault(file.Key.ContentType));
        var blob = containerClient.GetBlobClient(fileName);
        await blob.SetHttpHeadersAsync(new BlobHttpHeaders { ContentType = file.Key.ContentType });

        using (Stream stream = file.Key.OpenReadStream())
        {
            await blob.UploadAsync(stream);
        }

        filesInfo.Add(new SiteFile()
        {
            ContainerName = containerName,
            FileName = fileName
        });
    }

    await _siteDbContext.SiteFiles.AddRangeAsync(filesInfo);
    await _siteDbContext.SaveChangesAsync();

    // 直接提取自动生成的ID
    fileIDs = filesInfo.Select(f => f.Id).ToList();

    return fileIDs;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 22:15:27