C# 带有C接口的nHibernate(带Castle ActiveRecord)(特别是用于DTO和x27;s)

C# 带有C接口的nHibernate(带Castle ActiveRecord)(特别是用于DTO和x27;s),c#,asp.net,nhibernate,castle-activerecord,dto,C#,Asp.net,Nhibernate,Castle Activerecord,Dto,任何使用nHibernate的域对象和从公共接口实现的DTO对象?我试图将所有的nHibernate属性分离到域对象中,使DTO和接口保持干净 当nHibernate试图将接口与具体类相关联时,它会抛出错误 NHibernate.MappingException:关联引用未映射类:IContact 我理解为什么它抱怨使用非休眠界面,但我正在努力寻找一种可视化的方法来重新构建它。我的代码的骨架复制如下所示,关于如何更好地构造我的代码,有什么想法吗 public interface ICompany

任何使用nHibernate的域对象和从公共接口实现的DTO对象?我试图将所有的nHibernate属性分离到域对象中,使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; } }
}
公共接口公司
{
IList联系人{get;set;}
}
公共类公司收件人:i公司
{
私人联络;
公共IList联系人{get{返回this.Contacts;}set{this.Contacts=value;}}
}
[动态记录]
公共类公司:ActiveRecordBase,ICompany
{
私人联络;
[HasMany(Inverse=true,Table=“Contact”,ColumnKey=“CompanyId”)]
[脚本忽略]
公共IList联系人{get{返回this.Contacts;}set{this.Contacts=value;}}
}
编辑:


我希望有一个公共接口,这样我可以确保它们保持相同的字段(即依靠编译器保持一致)。它还允许我在应用程序的视图部分使用DTO,但将它们强制转换到域对象以进行业务和数据访问。
另外,alex的解决方案不起作用,因为ICompany的联系人是IList类型,而不是IList类型。我想将其保留为IContact,这样我的DTO对象就不知道Contact域对象

在您的域中,您不能使用IContract来引用域实体,而是使用具体类。如果要更正您的版本,只需使用以下命令:

[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; } }
}
[ActiveRecord]
公共类公司:ActiveRecordBase
{
私人联络;
[HasMany(Inverse=true,Table=“Contact”,ColumnKey=“CompanyId”)]
[脚本忽略]
公共IList联系人{get{返回this.Contacts;}set{this.Contacts=value;}}
}
我看不出连接域和DTO的意义。它们是耦合的,它们可以有不同的信息。例如,您可以将一些信息很小地封装到您的域中,而只传递很少的其他信息。DTO用于传输要与上层共享的数据

可以使用基类定义实体和ValueObject。简言之,实体:DomainEntity可标识意味着它们可以持久化。ValueObject=DTO无法持久化(不支持ID)

请看锐利拱门的核心设计:

  • /BaseObject.cs:提供基本的对象比较服务
  • /Entity.cs:提供具有域的对象 签名和可键入的ID属性。这也得到了验证 支持NHibernate验证器。从实体延伸的对象 必须至少有一个[DomainSignature]属性;它会抛出一个 如果违反此规定,则合同设计例外。接口 IEntityWithTypedID允许您自己滚动
  • /ValueObject.cs:这是一个值对象,其中所有 当与另一个值对象进行比较时,将使用属性。物体 从ValueObject扩展的可能没有任何[DomainSignature] 性质;如果是,它将抛出契约设计异常 违反了
在您的具体案例中,您只需在映射属性中添加
Type=typeof(Contact)
,如下所示:

[HasMany(Inverse=true, Table="Contact", ColumnKey="CompanyId", Type=typeof(Contact))]

如果我有[许多]属性,我该怎么办?它实际上没有属性名“Type”,但[property]和[BelongsTo]有

更新

答案是使用
CollectionType=typeof(YourType)

更新2

不,它不工作,此属性是为集合类型设置的,即列表等。
试图设置[HasMany(typeof(meType),…]),但仍然不起作用。

我希望有一个公共接口,以便确保它们保持相同的字段(即依靠编译器保持一致)。它还允许我在应用程序的视图部分使用DTO,但将它们强制转换为用于业务和数据访问的域对象。此外,您的解决方案不起作用,因为ICompany的联系人是IList类型,而不是IList类型。我希望将其保留为IContact,以便我的DTO对象不知道联系人域对象。很抱歉,进行了更改,删除了接口实现。您无法将ContactDto转换为直接联系人。您仍然需要使用转换。你可以将ContactDto转换为IContact,但不能转换为ContactHej,你也知道如何使用Fluent进行转换吗?:)