2009-07-20 2 views
12

Возможно ли иметь целочисленное свойство автоматического приращения класса, управляемого базой данных, но не быть первичным ключом (или Id как NHibernate относится к ним)? У меня возникли проблемы с поиском примеров того, как это сделать. Любая помощь будет оценена по достоинству. Благодарю.Свободное свойство nhibernate auto increment non key (Id)

ответ

9

Два варианта.

  • , если база данных 100% ответственность за это вам просто нужно сказать NHibernate, что свойство генерируется и не включать его в каком-либо обновления/isnerts. Недостатком является то, что NH необходимо будет сделать дополнительный выбор, чтобы сохранить значение свежее в памяти.

    < имя свойства = «Foo» создается = «всегда» обновление = «ложь» вставка = «ложь» />

  • , если база данных не несет ответственности, и вы просто хотите, чтобы это делалось автоматически вы можете используйте перехватчик, чтобы установить значение 1 в вставке и увеличить его на 1 при обновлении.

http://www.nhforge.org/doc/nh/en/index.html#objectstate-interceptors (11,1 - перехватчики)

Вы бы переопределить OnSave(), чтобы найти недвижимость и задать начальное значение и затем переопределить OnFlushDirty(), чтобы найти свойство собственности и приращения.


Edit:

Я идиот, не заметил, что ты сказал Fluent NHibernate.


Edit # 2:

Я думаю, вы могли бы быть заинтересованы в использовании этого столбца как управление версиями?

< version name="Foo" generated="always" /> 
+1

Не беспокойтесь, это почти то же самое. Карта (x => x.Foo) .ReadOnly().SetAttribute («сгенерировано», «всегда»); SetAttribute будет заменен на Generated.Always, когда мы нажмем 1.0. –

+0

Я загрузил последний FNH и был немного смущен .Update() не принимает параметр. Я не был уверен, что это закончится, как в картографии. ReadOnly() имеет смысл. – anonymous

5

Это работает для меня:

public class Potato 
{ 
    public virtual Guid Id { get; protected set; } 
    public virtual int LegacyId { get; protected set; } 
} 

public class PotatoMap : ClassMap<Potato> 
{ 
    public PotatoMap() 
    { 
     Id(x => x.Id).GeneratedBy.GuidComb(); 
     Map(x => x.LegacyId).CustomSqlType("INT IDENTITY(1,1)").Not.Nullable().ReadOnly().Generated.Insert(); 
    } 
} 

В принципе, число устанавливается на генерироваться в базе данных и NHibernate проинструктирован, чтобы получить его на вставках.

Важно отметить, что отображение является только половиной ответа, и оно будет не работать, если столбец не создан как идентификатор. CustomSqlType добавляется к сопоставлению с целью создания правильного sql при создании таблиц с помощью SchemaExport. Это сгенерированный SQL:

create table [Potato] (
     Id UNIQUEIDENTIFIER not null, 
     LegacyId INT IDENTITY(1,1) not null, 
     primary key (Id) 
    ) 

С другой стороны, ReadOnly и Generated.Insert() сообщит NHibernate, что значение генерируется автоматически с помощью базы данных только на вставках, и поэтому он должен запросить базу данных для значение в каждой вставке.

Обратите внимание, что я тестировал это только с помощью Sql Server. Пользовательский тип, вероятно, изменится или может быть недоступен в других базах данных.