1

JobLanguageの2 つのエンティティが多対 1 の関係にあります。これらのエンティティのマッピング構成は次のとおりです。

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 をオンにしてこのコードを実行すると、 JOBテーブルにINSERTする前に次の警告が表示されることです。

警告: 識別子 47 が割り当てられた en-GB が一時的なものか切り離されたものかを判断できません。データベースのクエリ。これを防ぐには、セッションで明示的な Save() または Update() を使用します。

続いて (不要) SELECTLANGUAGEテーブルから実行して、ID 47 のLanguageエンティティをロードします (「en-GB」はJob.SourceLanguageオブジェクトのコードです)。

私の場合、データベースからLanguageエンティティを更新、挿入、または削除したくありません(他のエンティティから参照されているだけの場合)。これは実際には不変のテーブルであり、常に正しい行で満たされています。NHibernate に、私から言語を取得し、 JOBテーブルに挿入するときに、そのIdプロパティを使用し、それがデータベースに存在するかどうかを気にしないように指示する方法はありますか?

ジョブをリポジトリに追加する前にこの行を追加すると

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

警告もSELECTも表示されなくなりましたが、 Languageエンティティを使用するすべての場所でこれを行うのは面倒です。

どうもありがとうございました。

4

1 に答える 1

2

オプションはインターセプタークラスを使用することです!これを追加してOnSaveメソッドをオーバーライドします

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

エンティティが「ジョブ」の場合。このようにして、どこでもこのクエリを実行する必要はありません。

たとえば、ここを見てください。

NHibernateIInterceptorの実装例

于 2011-06-13T15:12:32.480 に答える