NHibernateはSession.GetとSession.CreateCriteria差
-
21-09-2019 - |
質問
NHibernateはSession.Getとの違いは何ですかSession.CreateCriteria?
私の話があります:
私たちの製品では、インターフェイスISoftDeletable、このインタフェースはdeletedDateとdeletedByフィールドを持つ実装する各クラスを追加することにより、softDeletionを実施しました。 。CreatedDateに、CREATEDBY、modifiedDate、modifiedBy
:また、我々はそれを実装する各クラスが持っていることを意味AuditableEntityクラスを持っていますここではソースは次のとおりです:
public class SaveUpdateEventListener : DefaultSaveEventListener
{
private readonly ISecurityContextService securityContextService;
public SaveUpdateEventListener(ISecurityContextService securityContextService)
{
this.securityContextService = securityContextService;
}
protected override object PerformSaveOrUpdate(SaveOrUpdateEvent @event)
{
this.PrepareAuditableEntity(@event);
return base.PerformSaveOrUpdate(@event);
}
private void PrepareAuditableEntity(SaveOrUpdateEvent @event)
{
var entity = @event.Entity as AuditableEntity;
if (entity == null)
{
return;
}
if (this.securityContextService.EdiPrincipal == null)
{
throw new Exception("No logged user.");
}
if (entity.Id == 0)
{
this.ProcessEntityForInsert(entity);
}
else
{
this.ProcessEntityForUpdate(entity);
}
}
private void ProcessEntityForUpdate(AuditableEntity entity)
{
entity.ModifiedBy = securityContextService.GetLoggedUser();
entity.ModifiedDate = DateTime.Now;
}
private void ProcessEntityForInsert(AuditableEntity entity)
{
entity.CreatedBy = securityContextService.GetLoggedUser();
entity.CreatedDate = DateTime.Now;
}
また、我々はSession.Getメソッドをオーバーライドしている。
public virtual T Get(long id)
{
if (typeof(ISoftDeletable).IsAssignableFrom(typeof(T)))
{
return
this.Session.CreateCriteria(typeof(T))
.Add(Restrictions.Eq("Id", id))
//.Add(Restrictions.IsNull("DeletedDate"))
.UniqueResult<T>();
}
return Session.Get<T>(id);
}
現在、いくつかのコンテキストでアプリケーションがsoftDeletableと監査可能エンティティのGetメソッドでStackOverflowの例外をスロー。いくつかの調査の後、私はそれがPrepareEntityForUpdate / securityContextService.GetLoggedUser間のループを作成し、当社独自のリポジトリからのメソッドを取得していることを指摘しました。 あなたが見ることができるように私は、この手段はSession.Get(ID)を作成した基準と同じ結果を返す必要があること、DeletedDateに制限をコメントしました。しかし、私はthis.Session.CreateCriteria(typeof演算(T))ものの行けば、私はこの1つをコメントして残せば、私は、StackOverflowの例外を取得するだけで、すべてが正常に動作します。(対価のdeletiondateに取ることなく)Session.Get(ID)を返しますP>
これは私がSession.GetとSession.CreateCriteriaが異なる動作をすることを考えるようになります。 何か案は?
解決
取得は、セッションキャッシュを使用します。 基準はありません。
つまり、:基準は常にDBにSQLクエリ/コールになります。 常にSQLクエリにはなりません取得します。エンティティがすでにセッションでNHibernateのでロードされている、とあなたが得るを使用して再度エンティティーを検索したい場合は、NHibernateのは、それがすでにそのキャッシュからロードされたことのエンティティを返します。
他のヒント
これに加えて、あなたは、マッピングクラスでどこパラメータを設定することができます。あなたはそこに追加することができます: "DeletedDate IS NULLを"。取得が実行されるとNHibernateのは、生成されたクエリにこのWHEREステートメントを追加します。