Nhibernate производит прокси несмотря на выборку HQL
У меня есть следующее заявление HQL:
select distinct t from TaskEntity as
inner join fetch t.Case as c
inner join fetch c.Client as client
inner join fetch c.Matter as matter
Однако, несмотря на то, что Matter имеет FETCH против него, он все еще возвращается в качестве прокси.
Мое сопоставление для этого объекта ниже
References(x => x.Matter).Columns(new[] {"c_client","c_matter" });
Я пытался использовать JOIN для этого, но моя проблема, я иду от 1 до 2 столбцов, поэтому он не будет принимать сопоставление.
Какие-нибудь мысли?
Спасибо,
2 ответа
Я решил проблему, которая была причиной этой проблемы.
Это также разрешает составные идентификаторы!
Ранее в проекте Nhibernate предупреждал, что я не переопределяю Equals и GetHashCode, чтобы обойти множество изменений кода, и для содействия повторному использованию кода я создал класс CompositeBaseEntity:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Case.Infrastructure
{
public class BaseCompositeEntity : BaseEntity
{
public override int GetHashCode()
{
return base.GetHashCode();
}
public override bool Equals(object obj)
{
return base.Equals(obj);
}
}
}
Этот урок возвращает на место то, что Nhibernate велел мне избегать! Поскольку есть два ключа для сравнения равенства, мы ДОЛЖНЫ переопределить методы Equals & GetHashCode(), чтобы они стали чем-то вроде:
public override bool Equals(object obj)
{
if (obj == null)
return false;
var t = obj as ClientMatterEntity;
if (t == null)
return false;
if (AccountNumber== t.ClientAcconuntNumber && CaseNumber == t.CaseNumber)
return true;
return false;
}
Таким образом, Nhibernate точно знает, как должно выполняться сравнение, а затем знает, есть ли у него этот объект в кеше первого уровня (что он и сделает, как мы указали, fetch).
Дополнительную информацию можно найти здесь: http://nhforge.org/blogs/nhibernate/archive/2010/07/01/nhibernate-and-composite-keys.aspx
Помните, что вы также должны предоставить правильную реализацию GetHashCode.
Ваша реализация Equals тоже не велика.
Кроме того, оба метода должны возвращать "статические" значения. Я не видел ваш класс, но это должно быть что-то вроде:
public class TaskEntity
{
public int AccountNumber { get; protected set; }
public int CaseNumber { get; protected set; }
public Client Client { get; set; }
public Matter Matter { get; set; }
public TaskEntity(int accountNr, caseNr)
{
AccountNumber = accountNr;
CaseNumber = caseNr;
}
protected TaskEntity() {} // Needed for NHibernate proxies
}
Я действительно рекомендую помещать ваши идентификаторы компонентов в отдельные классы, когда это возможно.
Кроме того, прочитайте следующую статью о переопределении Equal, поскольку ваша текущая реализация, вероятно, имеет недостатки: http://msdn.microsoft.com/en-us/library/bsc2ak47.aspx особенно хорошо понимают часть, касающуюся наследования и базовых типов.