nHibernate (с Castle ActiveRecord) с интерфейсами C# (особенно для DTO)
-
10-07-2019 - |
Вопрос
Кто-нибудь использует nHibernate с объектом домена и объектом DTO, реализованным из общего интерфейса?Я пытаюсь разделить все атрибуты nHibernate на объект Domain, оставив DTO и интерфейс чистыми.
Проблема связана с тем, что nHibernate выдает ошибки, когда пытается связать интерфейсы с конкретными классами.
NHibernate.MappingException:Ассоциация ссылается на несопоставленный класс:IКонтакт
Я понимаю, почему он жалуется на использование интерфейса без гибернации, но я изо всех сил пытаюсь представить способ его реструктуризации.Скелет моего кода приведен ниже. Есть идеи, как лучше структурировать мой код?
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.Я хотел бы сохранить его как IContact, чтобы мой объект DTO не знал об объекте Contact Domain.
Решение
В вашем конкретном случае вам следует просто добавить 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.Вкратце Сущность:DomainEntity имеют возможность идентификации, что означает, что их можно сохранить.ValueObject = DTO не может быть сохранен (не поддерживается идентификатор)
Посмотрите на основной дизайн Sharp-Arch:
- /БазовыйОбъект.cs:Предоставляет базовые услуги по сравнению объектов.
- /Entity.cs:Предоставляет объект с доменной подписью и типичным идентификационным свойством.Это также имеет подтверждение поддержки Validator Nhibernate.Объекты, которые простираются от сущности, должны иметь как минимум одно свойство [домены];Это бросит исключение по дизайну за контрактом, если это будет нарушено.Интерфейс ientity withtypedid позволяет вам кататься.
- /ЗначениеОбъект.cs:Это объект значения, в котором все его свойства используются по сравнению с другим объектом значения.Объекты, которые распространяются от ValueObject, могут не иметь никаких свойств [доменной сигнализации];Это бросит исключение по дизайну за контрактом, если это будет нарушено.
И что мне делать, если у меня есть атрибут [HasMany]?На самом деле у него нет имени свойства «Тип», но есть свойства [Property] и [BelongsTo].
ОБНОВЛЯТЬ
Ответ заключается в использовании CollectionType = typeof(YourType)
ОБНОВЛЕНИЕ 2
Нет, это не работает, это свойство установлено для типа коллекции, т.е.Список и т. д.Пытаюсь установить [HasMany(typeof(meType), ...)], но все равно не работает.