композитный идентификатор nhibernate Fluent Mapping - PullRequest
3 голосов
/ 19 мая 2011

Я учусь использовать беглый nhibernate и не могу понять, как создавать свои отображения.У меня есть таблица с многоколоночным первичным ключом, но я не могу правильно отобразить его.У меня есть следующее беглое отображение -

public class MyEntityMappingOverride : IAutoMappingOverride<MyEntity>
    {
        public void Override(AutoMapping<MyEntity> mapping)
        {
            mapping.CompositeId()
                .KeyProperty(x => x.Id_1, "Id_1")
                .KeyProperty(x => x.Id_2, "Id_2");

            mapping.References(x => x.otherEntity)
                .Column("JoinColumn");

            // Commented out to attempt to map to another entity on multiple columns
            //mapping.HasMany(x => x.thirdEntit)
            //    .KeyColumns.Add("thirdId_1", "thirdId_2")
            //    .Cascade.All();



        }
    }

Проблема, с которой я сталкиваюсь, заключается в том, что составной идентификатор не работает.

Вот фрагмент из созданного файла сопоставления -

<id name="Id" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="Id" />
      <generator class="identity" />
    </id>

Затем я получаю сообщение об ошибке, что столбец (id) не найден ни в одной из таблиц в запросе.

Я ошибаюсь, полагая, что мой код сопоставления выдаст правильный составной идентификатор?Я что-то упускаю или что-то делаю неправильно?

1 Ответ

3 голосов
/ 19 мая 2011

Рекомендуется (и я добился большого успеха), что если вы используете CompositeKeys, вы используете объект ID в соответствии с:

NHibernate и Composite Keys

В вашем случае вы бы создали новый класс ...

[Serializable]
public MyEntityIdentifier
{
   public virtual TYPE Id_1;
   public virtual TYPE Id_2;

   // You need to override Equals(MyEntityIdentifier), Equals(object obj) and GetHashCode()
}

Тогда ваше отображение станет

public class MyEntityMappingOverride : IAutoMappingOverride<MyEntity>
{
        public void Override(AutoMapping<MyEntity> mapping)
        {
            mapping.CompositeId()
                .ComponentCompositeIdentifier(x => x.MyEntityIdentifier)
                .KeyProperty(x => x.MyEntityIdentifier.Id_1, Id_1, "Id_1")
                .KeyProperty(x => x.MyEntityIdentifier.Id_2, "Id_2");

            // snip
        }
}

И ваш класс перестанет иметь два свойства (Id_1 & Id_2) просто иметь MyEntityIdentifier.

Затем вы используете свой MyEntityIdentifier там, где требуется загрузить ..

MyEntity entity = Session.Load<MyEntity>(new MyEntityIdentifier { Id_1 = Whatever, Id_2 = Whatever });

А также, если у вас есть ЛЮБОЙ контроль над этой базой данных, я НАСТОЯТЕЛЬНО рекомендую не использовать CompositeKeys,В то время как NHibernate определенно справится с ними, у них есть немного дополнительных умственных сложностей и проблем.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...