NHibernate и объекты со значением-семантикой - PullRequest
0 голосов
/ 23 мая 2010

Проблема: если я передаю класс с семантикой значений (переопределенный метод Equals) в NHibernate, NHibernate пытается сохранить его в БД, даже если он просто сохранил сущность, равную по значению (но не по ссылке), в базу данных. Что я делаю не так?

Вот упрощенный пример модели для моей задачи:

Допустим, у меня есть Person сущность и City сущность. Один поток (производитель) создает новые объекты Person, которые принадлежат конкретному существующему городу, а другой поток (потребитель) сохраняет их в хранилище (используя NHibernate в качестве DAL).

Поскольку одновременно сбрасывается много объектов, я использую идентификаторы Guid.Comb, чтобы гарантировать, что каждая вставка выполняется с помощью одной команды SQL. Город - это объект с семантикой типа значения (равной только по имени - только для этого примера):

public class City : IEquatable<City>
{
    public virtual Guid Id { get; private set; }
    public virtual string Name { get; set; }

    public virtual bool Equals(City other)
    {
        if (other == null)
            return false;

        return this.Name == other.Name;
    }

    public override bool Equals(object obj)
    {
        return Equals(obj as City);
    }

    public override int GetHashCode()
    {
        return this.Name.GetHashCode();
    }
}

Беглое отображение NH - что-то вроде:

public class PersonMap : ClassMap<Person>
{
    public PersonMap()
    {
        Id(x => x.Id)
            .GeneratedBy.GuidComb();
        References(x => x.City)
            .Cascade.SaveUpdate();
    }
}

public class CityMap : ClassMap<City>
{
    public CityMap()
    {
        Id(x => x.Id)
            .GeneratedBy.GuidComb();
        Map(x => x.Name);
    }
}

Прямо сейчас (с моей текущей конфигурацией отображения NHibernate) мой потребительский поток поддерживает словарь городов и заменяет их ссылки в объектах входящих лиц (в противном случае NHibernate увидит новый, не кэшированный объект City и попытается также сохранить его). ), и мне нужно сделать это для каждого созданного объекта Person.

Поскольку я реализовал класс City, чтобы вести себя как тип значения, я надеялся, что NHibernate будет сравнивать города по значению, а не пытаться сохранять их каждый раз - т.е. мне нужно будет выполнять поиск только один раз за сеанс, и мне все равно о них больше.

Возможно ли это, и если да, что я здесь не так делаю?

Ответы [ 2 ]

3 голосов
/ 23 мая 2010

Переопределение Equals для сущности не заставляет NHibernate использовать для него «семантику значений».

Если вы вызовете session.Save для двух разных объектов, NHibernate попытается вставить их оба.

1 голос
/ 23 мая 2010

Когда Город является объектом-ценностью, он не должен иметь Идентификатор, поскольку его идентичность определяется на основании его значения.

Как правило, объекты значений объявляются как «компоненты» в NHibernate.

...