如何在nhibernate中映射接口?

时间:2010-02-18 06:17:50

标签: fluent-nhibernate

我正在使用两个班NiceCustomer& RoughCustomer实施接口ICustomer

ICustomer有四个属性。他们是:

  1. Property Id() As Integer
  2. Property Name() As String
  3. Property IsNiceCustomer() As Boolean
  4. ReadOnly Property AddressFullText() As String
  5. 我不知道如何将接口ICustomer映射到数据库。

    我在内部异常中遇到这样的错误。

      

    关联是指未映射的类:ICustomer

    我正在使用Fluent和NHibernate。

3 个答案:

答案 0 :(得分:3)

可以直接映射到NHibernate中的接口,方法是在配置阶段插入EmptyInterceptor。此拦截器的工作是为您在映射文件中定义的接口提供实现。

public class ProxyInterceptor : EmptyInterceptor
{
    public ProxyInterceptor(ITypeHandler typeHandler) {
        // TypeHandler is a custom class that defines all Interface/Poco relationships
        // Should be written to match your system
    }

    // Swaps Interfaces for Implementations
    public override object Instantiate(string clazz, EntityMode entityMode, object id)
    {
        var handler = TypeHandler.GetByInterface(clazz);
        if (handler == null || !handler.Interface.IsInterface) return base.Instantiate(clazz, entityMode, id);
        var poco = handler.Poco;
        if (poco == null) return base.Instantiate(clazz, entityMode, id);

        // Return Poco for Interface
        var instance = FormatterServices.GetUninitializedObject(poco);
        SessionFactory.GetClassMetadata(clazz).SetIdentifier(instance, id, entityMode);

        return instance;
    }

}

在此之后,所有关系和映射都可以定义为接口。

public Parent : IParent {
    public int ID { get; set; }
    public string Name { get; set; }
    public IChild Child { get; set; }
}

public Child : IChild {
    public int ID { get; set; }
    public string Name { get; set; }
}

public class ParentMap : ClassMap<IParent>
{
    public ParentMap()
    {
        Id(x => x.ID).GeneratedBy.Identity().UnsavedValue(0);
        Map(x => x.Name)
    }
}   

...

如果您希望实现ORM的真正解耦,将所有配置/映射放在单独的项目中并且仅引用接口,则此类技术非常有用。然后,您的域图层不会受到ORM的污染,如果需要,您可以在以后更换它。

答案 1 :(得分:0)

无法在nhibernate中映射接口。如果您的目标是能够使用通用类型进行查询以检索两种类型的客户,则可以使用多态查询。只需让您的类实现接口并正常映射类。请参阅此参考:

https://www.hibernate.org/hib_docs/nhibernate/html/queryhql.html(第11.6节)

答案 2 :(得分:0)

你好,如何查询?如果您正在使用HQL,则需要使用以下行的HBM文件导入接口的命名空间:

<import class="name.space.ICustomer, Customers" />

如果您正在使用Criteria,您应该只能查询ICustomer,它将返回两种客户类型。

如果您要通过HasMany,HasManyToMany或References映射具有客户的类,则需要使用通用表单:

References<NiceCustomer>(f=>f.Customer)

如果你想让它处理任何一个,你需要让它们成为子类

Subclassmap<NiceCustomer>

在这种情况下,我认为您需要基类Customer并将其用于外部类中的泛型类型参数:

References<Customer>(f=>f.Customer)

无论如何,你不应该改变你的域模型来应对这种情况,它应该在外层上有一个ICustomer。

我不确定1.0RTM是否有Generic表格可供参考,但快速扫描更改应显示更改,我认为这是一个两行添加。