31

我刚刚切换到 Fluent NHibernate,但遇到了一个问题,但没有找到任何相关信息。

情况如下:

public class Field : DomainObject, IField
{
    public Field()
    {  
    }

    public virtual string Name { get; set; }
    public virtual string ContactPerson { get; set; }
    public virtual bool Private { get; set; }
    public virtual IAddress Address { get; set; }  
}

IAddress 是由一个名为 Address 的类实现的接口

public class Address : DomainObject, IAddress
{
    public Address()
    {
    }

    public virtual string City { get; set; }
    public virtual string Country { get; set; }
    public virtual string PostalCode { get; set; }
    public virtual string StreetAddress { get; set; }
}

这是我的两个类的映射文件

地址

public class AddressMap : ClassMap<Address>
{   
    public AddressMap()
    {
        WithTable("Addresses");
        Id(x => x.Id, "Id").Access.AsCamelCaseField(Prefix.Underscore).GeneratedBy.Guid();
        Map(x => x.City, "City");
        Map(x => x.Country, "Country");
        Map(x => x.PostalCode, "PostalCode");
        Map(x => x.StreetAddress, "StreetAddress");
    }
}

场地

public class FieldMap : ClassMap<Field>
{
    public FieldMap()
    {
        WithTable("Fields");
        Id(x => x.Id, "Id").Access.AsCamelCaseField(Prefix.Underscore).GeneratedBy.Guid();
        Map(x => x.Name, "Name");
        Map(x => x.ContactPerson, "ContactPerson");
        Map(x => x.Private, "Private");
        References(x => x.Address, "AddressId").Cascade.Delete().Cascade.SaveUpdate();
    }
}

因此,当我尝试从数据库中检索字段对象时,我收到 NHibernate 错误,指出 IAddress 未映射。有没有办法指定 NHibernate 在映射中使用 Address 类?

如果需要更多信息,请告诉我。

非常感谢,

查尔斯

4

3 回答 3

36

我发现使用接口而不是具体类作为属性是有正当理由的。

例如,如果您的 Field 类与 Address 类位于一个单独的项目中,并且您没有从 Field 类的项目中依赖 Address 类的项目。

还有其他处理这种情况的方法,但最简单的方法通常是尝试您正在做的事情并明确告诉 NHibernate 用于 IAddress 的具体类。

您现在可以在 Fluent NHibernate 中执行此操作,如下所示:

References(x => x.Address, "AddressId")
    .Class(typeof(Address);

不幸的是,你不能用 HasMany 或 HasManyToMany 做到这一点。由于 C# 中缺乏良好的协方差支持,我不确定这是否可能。

于 2010-01-22T00:28:59.353 回答
5

在您的 Field 对象上,您有一个 IAddress 类型的对象。这可以通过任意数量的不同实现来实现。根据您的要求,每个实现都会有自己的映射,这会给 NHibernate 带来许多困难(不可能?)。

一个简单的例子将有助于演示。假设您有两个 IAddress 实现 Address1 和 Address2。它们都保存在自己的表 tblAddress1 和 tblAddress2 中。当您尝试加载您的 Field 对象时,NHibernate 所知道的只是您有实现 IAddress 的东西,它不知道哪个实现被持久化。它如何知道使用哪个映射来检索任何给定字段的子对象?

我敢肯定还有更多的复杂性,但这个例子说明了为什么你必须为你声明的确切类型的对象进行映射。

于 2009-03-25T20:41:37.893 回答
0

如果您有兴趣将 ORM 完全与域层分离,并在整个数据层中引用接口而不是指定具体的类,则可以实现 EmptyInterceptor 以在两者之间进行映射。

在这里查看我的答案。

于 2014-02-17T10:02:42.797 回答