これは本当に遅いですが、似たようなことをしようとしている次の人に役立つかもしれません:
ほとんどの場合、識別子を変更すべきではないという他の回答は正しいですが、マップされたプロパティを巧妙に使用して、純粋に NH (ネイティブ SQL なし) の範囲内で行うことができます。FluentNH を使用した要点は次のとおりです。
public enum CustomerType //not sure it's needed
{
Customer,
TierOneCustomer
}
public class Customer
{
//You should be able to use the Type name instead,
//but I know this enum-based approach works
public virtual CustomerType Type
{
get {return CustomerType.Customer;}
set {} //small code smell; setter exists, no error, but it doesn't do anything.
}
...
}
public class TierOneCustomer:Customer
{
public override CustomerType Type {get {return CustomerType.TierOneCustomer;} set{}}
...
}
public class CustomerMap:ClassMap<Customer>
{
public CustomerMap()
{
...
DiscriminateSubClassesOnColumn<string>("CustomerType");
DiscriminatorValue(CustomerType.Customer.ToString());
//here's the magic; make the discriminator updatable
//"Not.Insert()" is required to prevent the discriminator column
//showing up twice in an insert statement
Map(x => x.Type).Column("CustomerType").Update().Not.Insert();
}
}
public class TierOneCustomerMap:SubclassMap<TierOneCustomer>
{
public CustomerMap()
{
//same idea, different discriminator value
...
DiscriminatorValue(CustomerType.TierOneCustomer.ToString());
...
}
}
最終的な結果は、識別子の値が挿入用に指定され、検索時にインスタンス化された型を決定するために使用されますが、同じ Id を持つ別のサブタイプのレコードが保存された場合 (あたかもレコードが複製されたか、バインドされていないかのように) です。 UI を新しいタイプに)、その ID をオブジェクト プロパティとして既存のレコードで識別子の値が更新されるため、そのタイプの今後の取得は新しいオブジェクトとして行われます。AFAIK NHibernate は、プロパティが読み取り専用 (したがって、DB への「書き込み専用」) であると判断できないため、プロパティにはセッターが必要です。NHibernate の世界では、DB に何かを書き込んだ場合、なぜそれを返してほしくないのでしょうか?
私は最近、このパターンを使用して、ユーザーが「ツアー」の基本的なタイプを変更できるようにしました。これは実際には、実際の「ツアー」(クライアントのオンサイト機器への単一のデジタル「訪問」) のスケジュールを管理する一連のルールです。すべてが正しく機能することを確認します)。それらはすべて「ツアースケジュール」であり、リスト/キューなどで収集できる必要がありますが、さまざまなタイプのスケジュールには非常に異なるデータと非常に異なる処理が必要であり、OP と同様のデータ構造が必要です。したがって、データ層での影響を最小限に抑えながら、TierOneCustomer を実質的に異なる方法で扱いたいという OP の要望を完全に理解しています。