我有两个实体,作业和语言,处于多对一关系中。这些实体的映射配置如下:
public class JobMap : ClassMap<Job>
{
public JobMap()
{
Table("\"JOB\"");
LazyLoad();
Id(x => x.Id, "id").GeneratedBy.HiLo("hilo", "hilo_job", "50");
Map(x => x.Name).Column("name").Unique();
References<Language>(x => x.SourceLanguage, "fk_id_language").Cascade.None();
}
}
public class LanguageMap : ClassMap<Language>
{
public LanguageMap()
{
Table("\"LANGUAGE\"");
LazyLoad();
Id(x => x.Id, "id").GeneratedBy.Assigned().UnsavedValue(0);
Map(x => x.Code).Column("code");
}
}
我使用此代码将作业添加到数据库
private IServiceOperationResult AddJob(string jobName, Language sourceLanguage)
{
try
{
ISession session = sessionBuilder.GetSession();
using (ITransaction transaction = session.BeginTransaction(System.Data.IsolationLevel.Serializable))
{
job = new Job(jobName, sourceLanguage);
jobRepository.Add(job);
transaction.Commit();
}
}
catch (Exception e)
{
log.Error("Error adding job to the DB", e);
return new StringServiceOperationResult(e);
}
return new OkOperationResult();
}
JobRepository.Add(作业)很简单
public void Add(Job entity)
{
SessionBuilder.GetSession().Save(entity);
}
问题是在启用NHProfiler的情况下运行此代码,我可以在 INSERT 之前看到以下警告进入 JOB 表:
WARN: 无法确定分配了标识符47的en-GB是暂时的还是分离的;查询数据库。在会话中使用显式Save()或Update()来防止这种情况。
然后从 LANGUAGE 表中的(不必要的) SELECT 加载语言实体,其ID为47(其中“en-GB”是 Job.SourceLanguage 对象的代码。
在我的情况下,我不希望从数据库中更新,插入或删除语言实体(在刚从其他实体引用的情况下),它实际上是不可变的表,填充始终使用正确的行。有没有办法让NHibernate从我这里获取语言,并在插入 JOB 表时,使用其 Id 属性而不是关心它是否存在于数据库中?
在将作业添加到存储库
之前添加此行job.SourceLanguage = session.Load<Language>(sourceLanguage.Id);
我不再收到警告,也没有 SELECT ,但在使用语言实体的任何地方执行此操作都很麻烦。
非常感谢。
答案 0 :(得分:1)
一个选项是使用拦截器类!覆盖添加此
的OnSave方法job.SourceLanguage = session.Load<Language>(sourceLanguage.Id);
当实体是“工作”时。通过这种方式,您无需在任何地方进行此查询。
在这里查看例如: