У меня есть два теоретических объекта домена:
публичный класс Person { public virtual int Id {get; частный набор; } }
public class PersonMap : ClassMap<Person>
{
public PersonMap() { Id( x => x.Id ); }
}
public class DriversLicense
{
public virtual Person Person { get; set; }
public virtual string State { get; set; }
}
public class DriversLicenseMap : ClassMap<DriversLicense>
{
public DriversLicenseMap()
{
References( x => x.Person );
Map( x => x.State );
}
}
Если объект Person должен использоваться как PK для DriversLicense. Я не хочу, чтобы объект Person имел какие-либо знания о DriversLicense, поэтому отношения поддерживаются строго в классе DriversLicense. Существует ровно один DriversLicense на человека.
При настройке таким образом я получаю следующее исключение:
System.Xml.Schema.XmlSchemaValidationException: Элемент 'class' в пространстве имен 'urn: nhibernate-mapping-2.2' имеет недействительный дочерний элемент 'свойство' в Пространство имен 'Урна: NHibernate-отображение-2,2'. Список ожидаемые элементы: "мета, jcs-cache, cache, id, composite-id 'в Пространство имен. 'Урны: NHibernate-отображение-2,2'
Добавление свойства Id в тип DriversLicense устраняет проблему.
Есть ли способ использовать сам Person в качестве первичного ключа в таблице DriversLicense, чтобы базовая таблица просто использовала Person.Id для этого первичного ключа?
Можно использовать комбинированный ключ? http://nhibernate.info/doc/nh/en/index.html#mapping-declaration-compositeid http://nhibernate.info/doc/nh/en/index.html#components-compositeid
@Matthieu получил меня на правильном пути с составными клавишами. Мне пришлось использовать метод UseCompositeId(), а затем переопределить Equals и GetHashCode для объекта License License.
Вот как это выглядит в беглом NHibernate:
public class DriversLicense
{
public virtual Person Person { get; set; }
public virtual string State { get; set; }
public override bool Equals( object obj )
{
if( ReferenceEquals( obj, null ) ) return false;
// Cast, instead of 'as' throws runtime exception when obj is not an
// DriversLicense.
var comp = (DriversLicense) obj;
if( Person == null || comp.Person == null )
return false;
return Person.Equals( comp.Person );
}
public override int GetHashCode()
{
return Account == null ? -1 : Account.GetHashCode();
}
}
public class DriversLicenseMap : ClassMap<DriversLicense>
{
public DriversLicenseMap()
{
UseCompositeId().WithKeyReference( x => x.Person );
Map( x => x.State );
}
}