nHibernate(w / Castle ActiveRecord)とC#インターフェイス(DTOの場合はesp)
-
10-07-2019 - |
質問
nHibernateをDomainオブジェクトと一緒に使用する場合&共通インターフェースから実装されたDTOオブジェクト?すべてのnHibernateの属性をDomainオブジェクトに分離し、DTOとインターフェイスをクリーンな状態にしようとしています。
問題は、nHibernateがインターフェイスを具象クラスに関連付けようとするときにエラーをスローすることで発生します。
NHibernate.MappingException:関連付けがマップされていないクラスを参照:IContact
休止状態になっていないインターフェースの使用について文句を言う理由は理解できますが、視覚的にその周辺を再構築する方法に苦労しています。コードのスケルトン複製は以下のように設定されていますが、コードをよりよく構成するためのアイデアはありますか?
public interface ICompany
{
IList<IContact> Contacts { get; set; }
}
public class CompanyDTO : ICompany
{
private IList<IContact> contacts;
public IList<IContact> Contacts { get { return this.contacts; } set { this.contacts = value; } }
}
[ActiveRecord]
public class Company : ActiveRecordBase<Company>, ICompany
{
private IList<IContact> contacts;
[HasMany(Inverse=true, Table="Contact", ColumnKey="CompanyId")]
[ScriptIgnore]
public IList<IContact> Contacts { get { return this.contacts; } set { this.contacts = value; } }
}
編集:
同じフィールドを保持していることを確認できるように、共通のインターフェースが必要です(つまり、一貫性を保つためにコンパイラーに頼っています)。また、アプリケーションのビュー部分でDTOを使用できますが、ビジネスおよびデータアクセスのためにドメインオブジェクトにキャストします。 また、ICompanyの連絡先はIListではなくIList型であるため、alexのソリューションは機能しません。 DContactオブジェクトがContact Domainオブジェクトの知識を持たないように、IContactのままにしておきます。
解決
具体的なケースでは、次のようにマッピング属性に Type = typeof(Contact)
を追加するだけです。
[HasMany(Inverse=true, Table="Contact", ColumnKey="CompanyId", Type=typeof(Contact))]
他のヒント
ドメインでは、IContractを使用してドメインエンティティを参照することはできません。代わりにConcreteクラスを使用します。バージョンを修正したい場合は、これを使用してください:
[ActiveRecord]
public class Company : ActiveRecordBase<Company>
{
private IList<Contact> contacts;
[HasMany(Inverse=true, Table="Contact", ColumnKey="CompanyId")]
[ScriptIgnore]
public IList<Contact> Contacts { get { return this.contacts; } set { this.contacts = value; } }
}
ドメインとDTOを接続するポイントがわかりません。これらは結合されており、同じ情報を持つことはできません。たとえば、いくつかの情報をドメインにカプセル化して、他の情報をほとんど伝えないようにすることができます。 DTOは、上位レイヤーと共有するデータを転送するために作成されます。
ベースクラスを使用して、エンティティとValueObjectを定義できます。簡単に言うと、Entity:DomainEntityはIDが可能であるという意味です。 ValueObject = DTOは永続化できません(ID不可)
Sharp-Archのコアデザインを見る:
- /BaseObject.cs:基本的なオブジェクト比較サービスを提供します。
- /Entity.cs:オブジェクトにドメインを提供します 署名と入力可能なIDプロパティ。これには検証もあります NHibernate Validatorのサポート。エンティティから拡張されるオブジェクト 少なくとも1つの[DomainSignature]プロパティが必要です。それは投げます これに違反した場合、Design-By-Contract例外。インターフェース IEntityWithTypedIDを使用すると、独自のロールを実行できます。
- /ValueObject.cs:これは値オブジェクトであり、すべての プロパティは、別の値オブジェクトと比較するときに使用されます。オブジェクト ValueObjectから拡張されるものには、[DomainSignature]を含めることはできません。 プロパティ;これが次の場合、Design-By-Contract例外をスローします。 違反した。
[HasMany]属性がある場合はどうすればよいですか?実際にはプロパティ名「Type」はありませんが、[Property]と[BelongsTo]にはあります。
更新
答えは、 CollectionType = typeof(YourType)
UPDATE 2
いいえ、機能しません。このプロパティはコレクションタイプ、つまりリストなどに設定されます。 [HasMany(typeof(meType)、...)]を設定しようとしましたが、まだ機能しません。