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

如何在NHibernate中使用InsertBuilder实现批量插入时生成唯一Guid

解决NHibernate InsertBuilder批量插入生成唯一Guid的问题

问题原因

你当前的写法报错是因为InsertBuilder会将操作转换为SQL语句在数据库端执行,而guidGen.Generate(s.GetSessionImplementation(), c)是客户端方法调用,无法被NHibernate解析为合法的SQL表达式,因此抛出“The property expression must refer to a property of c(Attachment)”错误。

下面提供两种可行的解决方案:


方案一:利用数据库内置Guid生成函数(推荐)

直接让数据库生成唯一Guid,性能更优且无需加载数据到内存,适合大数据量批量插入场景。根据你使用的数据库调整函数名:

示例代码(SQL Server)

var mailIds = batch.Select(x => x.Id);

Dao.Evaluate(s => s.Query<Mail>()
    .Where(es => mailIds.Contains(es.Id))
    .InsertBuilder()
    .Into<Attachment>()
    // 使用SQL Server的NEWID()函数生成唯一Guid
    .Value(c => c.Id, Projections.SqlFunction("newid", NHibernateUtil.Guid))
    .Value(c => c.Filename, fileName)
    .Value(c => c.Type.Id, attachmentType.Id)
    .Value(c => c.Media.Id, media.Id)
    .Value(c => c.LastChangedBy, IdentityHelper.CurrentUserName)
    .Value(c => c.LastChangedOn, DateTime.Now)
    .Value(c => c.CreatedBy, IdentityHelper.CurrentUserName)
    .Value(c => c.CreatedOn, DateTime.Now)
    .Insert());

其他数据库适配

  • PostgreSQL:替换为Projections.SqlFunction("uuid_generate_v4", NHibernateUtil.Guid)(需先安装uuid-ossp扩展)
  • MySQL:替换为Projections.SqlFunction("uuid", NHibernateUtil.Guid)

方案二:客户端预生成Guid后批量插入

如果需要在客户端控制Guid生成逻辑,可先将源数据加载到内存,生成包含唯一Guid的Attachment集合,再执行批量插入:

示例代码

var mailIds = batch.Select(x => x.Id);

// 1. 加载需要关联的Mail数据到内存
var targetMails = Dao.Evaluate(s => 
    s.Query<Mail>().Where(es => mailIds.Contains(es.Id)).ToList());

// 2. 生成带唯一Guid的Attachment集合
var attachments = targetMails.Select(_ => new Attachment
{
    Id = Guid.NewGuid(), // 客户端生成唯一Guid
    Filename = fileName,
    Type = attachmentType,
    Media = media,
    LastChangedBy = IdentityHelper.CurrentUserName,
    LastChangedOn = DateTime.Now,
    CreatedBy = IdentityHelper.CurrentUserName,
    CreatedOn = DateTime.Now
    // 若Attachment与Mail有关联,需补充关联属性,如: Mail = _
}).ToList();

// 3. 批量插入(需确保NHibernate配置了批量插入:如设置adonet.batch_size)
Dao.Evaluate(s =>
{
    s.SaveOrUpdateAll(attachments);
    s.Flush();
});

注意事项

  • 需在NHibernate配置文件中开启批量插入优化:<property name="adonet.batch_size">50</property>(数值根据数据量调整)
  • 此方案会将源Mail数据加载到内存,数据量过大时需注意内存占用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 19:25:00