Справочная информация
У меня есть следующий класс, который я хочу сопоставить с 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
)
ScreenName проигрывателя может быть адресом электронной почты ("foo@bar.com"), псевдонимом в 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);
}
}
Но свойство Unsubscribeed сложнее, потому что мне нужно получить эту информацию из двух устаревших таблиц, которые я не могу изменить, и которые ядолжен иметь доступ только для чтения (никакие вставки, обновления или удаления не разрешены):
-- Legacy tables, can't change
EmailAddress (
int Id
string EmailAddress (not null) -- "foo@bar.com"
)
Unsubscribed (
int Id
int EmailAddressId (not null) -- foreign key to EmailAddress table
)
Отписаться могут только игроки по электронной почте, так что у игроков других типов никогда не будет строк ни в EmailAddress, ни вНеподписанная таблица.
Это классы унаследованных таблиц:
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; }
}
И вот их беглые отображения:
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");
}
}
Задача
Проблема, с которой я столкнулся при попытке получить отписанную информацию для игроков по электронной почте.
Единственный способ, которым я могу связать таблицу Unsubscribeed с таблицей Player, - через промежуточную таблицу EmailAddress, соответствующуюEmailAddress.EmailAddress для Player.AddressIdentifier, но у меня возникают проблемы при попытке выяснить, как это сделать с помощью Fluent NHibernate.
Я посмотрел на Соединение для нескольких таблиц, но все примеры, которые я нашел, касаются только двух таблиц, а не трех:
- Объединение таблиц с использованиемСвободный NHibernate
- Свободный Nhibernate левое соединение