私のエンティティのいくつかは、すべてがEvent
リストプロパティを共有しているため、基本クラスを作成したいと思います。 Event
リストを読み取り専用プロパティにしたいと考えています。Fluent NHibernate基本クラスのreadonlyプロパティを正しくマップします
私はベースEventRelatedEntity
クラスを作成し、それをイベントと関係があるエンティティクラスごとに派生させました。
また、テーブルにリンクされていないので、EventRelatedEntity
クラスにはNHibernateマッピングクラスはありません。
以下のコードを参照してください。
基本クラス:
public class EventRelatedEntity
{
private readonly List<Event> events;
public virtual IReadOnlyCollection<Event> Events { get; protected set; }
public EventRelatedEntity()
{
events = new List<Event>();
Events = events.AsReadOnly();
}
protected virtual void AddEvent<T>(T entity, string message)
{
if (events == null)
events = new List<Event>();
Event newEvent = new Event();
if (typeof(T) == typeof(Company))
{
newEvent.CompanyId = (entity as Company).Id;
// ...and do some other stuff...
}
else if (typeof(T) == typeof(Document))
{
newEvent.DocumentId = (entity as Document).Id;
// ...and do some other stuff...
}
else if (typeof(T) == typeof(Typology))
{
newEvent.TypologyId = (entity as Typology).Id;
// ...and do some other stuff...
}
newEvent.Message = message;
events.Add(newEvent);
}
}
エンティティクラス
public class Company : EventRelatedEntity
{
[Key]
public virtual int Id { get; protected set; }
[Required]
public virtual string Alias { get; set; }
[Required]
public virtual string CompanyName { get; set; }
// ...and some other properties...
#region Actions
public virtual void AddEvent(string message)
{
base.AddEvent(this, message);
}
#endregion
}
public class Document : EventRelatedEntity
{
[Key]
public override int Id { get; protected set; }
[Required]
public virtual User User { get; protected set; }
// ...and some other properties...
#region Actions
public virtual void AddEvent(string message)
{
base.AddEvent(this, message);
}
#endregion
}
// ...and some other classes...
エンティティのため流暢NHibernateのマッピングクラス
public class CompanyMap : ClassMap<Company>
{
public CompanyMap()
{
Table("Companies");
LazyLoad();
Id(x => x.Id).GeneratedBy.Identity().Column("Id");
Map(x => x.Alias).Column("Alias").Not.Nullable();
Map(x => x.CompanyName).Column("CompanyName").Not.Nullable();
// ...and some other mappings...
// Link with Events table
HasMany(x => x.Events) // Events is declared in the base class (EventRelatedEntity)
.KeyColumn("CompanyId")
.Access.LowerCaseField()
.Cascade.AllDeleteOrphan();
}
}
public class DocumentMap : ClassMap<Document>
{
public DocumentMap()
{
Table("Documents");
LazyLoad();
Id(x => x.Id).GeneratedBy.Identity().Column("Id");
References(x => x.User).Column("UserId");
// ...and some other mappings...
// Link with Events table
HasMany(x => x.Events) // Events is declared in the base class (EventRelatedEntity)
.KeyColumn("DocumentId")
.Access.LowerCaseField()
.Cascade.AllDeleteOrphan();
}
}
// ...and some other mapping classes...
最後に、List<>.Add()
メソッドへの直接アクセスを避けたいと思います。私は読み取り専用のコレクションが欲しい。新しいEvent
をエンティティのイベントリストに追加する唯一の方法は、対応するエンティティクラスのAddEvent
メソッドでなければなりません。
例:
Document document = session.Get<Document>(1);
// ...the same for other derived classes...
// I WANT TO AVOID THIS!
document.Events.Add(new Event());
// WANTS TO BE THE ONLY PERMITTED WAY TO ADD NEW EVENTS
document.AddEvent("My new event message");
問題は、私がやるときということです:
Document document = session.Get<Document>(1);
私はNHibernateのからのエラーを取得:
Cannot cast objects of type 'NHibernate.Collection.Generic.PersistentGenericBag'1 [SolutionDOC_Interface.Entity.Event]' to the 'System.Collections.Generic.List'1 [SolutionDOC_Interface.Entity.Event]' type.
私はそれはと関連していると思います実際にはEventRelatedEntity
クラスはNHibernateマッピングを持っていませんが、マップを提供することはできません。 o DB内の表を使用します。 継承を使わずに各クラス(Company、Documentなど)の中でイベントリストを宣言した場合、NHibernateは機能しますが、このアプローチでは避けたいコードの複製がかなり生成されます。 @ryanのようなコードを変更した後
UPDATE 2017年10月18日
は、それが動作するようになりまし提案。
改訂コード:
public class EventRelatedEntity
{
private readonly IList<Event> events;
public virtual IReadOnlyCollection<Event> Events { get; protected set; }
public EventRelatedEntity()
{
events = new List<Event>();
Events = (events as List<Event>).AsReadOnly();
}
// ...
}
ような問題をいただきましたか!?もし 'Events'が本当に' IReadOnlyCollection'として宣言されていれば 'document.Events.Add(new Event());'はエラーを生成しているはずです: ''IReadOnlyCollection 'は' Add 'の定義を含んでいません。 " –
ryan
NHibernateエラーが発生しました。私は質問を更新しました。 –