背景情報
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
)
Player の ScreenName には、電子メール アドレス ("foo@bar.com")、Twitter のスクリーン名 ("@FooBar")、Skype のスクリーン名 ("foo.bar")、またはそのようなものを指定できます。Fluent NHibernate を使用して Player の最初の 3 つのプロパティをマッピングするのは簡単です。
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 プロパティは、変更できず、読み取り専用 (挿入、更新、または削除が許可されていない) でアクセスする必要がある 2 つの従来のテーブルからその情報を取得する必要があるため、より困難です。
-- 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
)
購読を解除できるのは電子メール Player のみであるため、他のタイプの Player は 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 を Player.AddressIdentifier に一致させる中間の EmailAddress テーブルを使用することですが、Fluent NHibernate でこれを行う方法がわかりません。
複数のテーブルの Join を見てきましたが、私が見つけたすべての例では、3 つではなく 2 つのテーブルしか扱っていません。