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 особенно хорошо понимают часть, касающуюся наследования и базовых типов.

Другие вопросы по тегам