【问题标题】:Using 'Assigned' ID with NHibernate在 NHibernate 中使用“分配的”ID
【发布时间】:2011-06-13 15:02:53
【问题描述】:

我有两个实体,JobLanguage,具有多对一的关系。这些实体的映射配置如下:

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(Job job) 很简单

public void Add(Job entity)
{
    SessionBuilder.GetSession().Save(entity);
}

问题是在打开 NHProfiler 的情况下运行此代码,我可以在 INSERT 进入 JOB 表之前看到以下警告:

警告: 无法确定分配标识符为 47 的 en-GB 是暂时的还是分离的;查询数据库。在会话中使用显式 Save() 或 Update() 来防止这种情况发生。

后跟(不必要的)SELECTLANGUAGE 表中加载 ID 为 47 的 Language 实体(其中“en-GB”是 Job.SourceLanguage 对象的代码)。

就我而言,我不想从数据库中更新、插入或删除 Language 实体(在它只是从其他实体引用的情况下),它实际上是不可变的表,已填充始终使用正确的行。有没有办法告诉 NHibernate 只从我那里获取 Language 并在插入 JOB 表时使用它的 Id 属性而不是关心它是否存在于数据库中?

当我在将 Job 添加到存储库之前添加此行时

job.SourceLanguage = session.Load<Language>(sourceLanguage.Id);

我不再收到警告或 SELECT,但在我使用 Language 实体的任何地方都执行此操作有点麻烦。

非常感谢。

【问题讨论】:

    标签: c# nhibernate transient


    【解决方案1】:

    一个选项是使用拦截器类!覆盖 OnSave 方法添加此

    job.SourceLanguage = session.Load<Language>(sourceLanguage.Id);
    

    当实体是“工作”时。这样你就不必到处做这个查询了。

    例如看这里:

    Sample NHibernate IInterceptor implementation

    【讨论】:

    • 非常感谢!这看起来是一个优雅的解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多