Справочная информация
У меня есть следующий класс, который я хочу сопоставить с NHibernate:
public class Player
{
public virtual int Id { get; set; }
public virtual Type Type { get; set; }
public virtual string ScreenName { get; set; }
public virtual bool Unsubscribed { get; set; }
}
На стороне базы данных у меня есть следующие таблицы:
-- New table
Player (
int Id
int TypeId (not null) -- foreign-key to Type table
string ScreenName (not null) -- can be an EmailAddress, but not necessarily
)
Type (
int Id
string Name -- "Email", "Facebook", etc
)
Экранным именем игрока может быть адрес электронной почты («[email protected]»), экранное имя Twitter («@FooBar»), экранное имя Skype («foo.bar») или что-то еще в этом роде. Сопоставить первые три свойства Player с помощью Fluent NHibernate достаточно просто:
public class PlayerMap : ClassMap<Player>
{
public PlayerMap()
{
Id(x => x.Id);
Map(x => x.ScreenName)
.Not.Nullable();
References(x => x.Type)
.Column("TypeId")
}
}
public class TypeMap : ClassMap<Type>
{
public TypeMap()
{
Id(x => x.Id);
Map(x => x.Name);
}
}
Но свойство Unsubscribed сложнее, потому что мне нужно получить эту информацию из двух устаревших таблиц, которые я не могу изменить и к которым я должен получить доступ в режиме только для чтения (вставки, обновления или удаления не разрешены):
-- Legacy tables, can't change
EmailAddress (
int Id
string EmailAddress (not null) -- "[email protected]"
)
Unsubscribed (
int Id
int EmailAddressId (not null) -- foreign key to EmailAddress table
)
Отписаться можно только от игроков по электронной почте, поэтому у игроков других типов никогда не будет строки ни в EmailAddress, ни в таблице Unsubscribed.
Это классы устаревших таблиц:
public class EmailAddress
{
public virtual int Id { get; set; }
public virtual string Value { get; set; }
public virtual IList<Unsubscription> Unsubscriptions{ get; set; }
}
public class Unsubscription
{
public virtual int Id { get; set; }
public virtual EmailAddress EmailAddress { get; set; }
}
А вот их сопоставления Fluent:
public class EmailAddressMap : ClassMap<EmailAddress>
{
public EmailAddressMap()
{
ReadOnly();
Id(x => x.Id);
Map(x => x.Value)
.Column("EmailAddress")
.Not.Nullable();
HasMany(x => x.Unsubscriptions)
.KeyColumn("EmailAddressId");
}
}
public class EmailOptOutMap : ClassMap<EmailOptOut>
{
public EmailOptOutMap()
{
ReadOnly();
Id(x => x.Id);
References(x => x.EmailAddress)
.Column("EmailAddressId");
}
}
Проблема
Моя проблема заключается в попытке получить информацию об отказе от подписки для игроков по электронной почте.
Единственный способ связать таблицу Unsubscribed с таблицей Player - это использовать промежуточную таблицу EmailAddress, соответствующую EmailAddress.EmailAddress и Player.AddressIdentifier, но мне сложно понять, как это сделать с помощью Fluent NHibernate.
Я посмотрел на Join для нескольких таблиц, но все примеры, которые я нашел, относятся только к двум таблицам, а не к трем: