具有接口引用的FluentNHibernate AutoPersistenceModel

时间:2010-12-13 10:14:59

标签: c# .net nhibernate interface fluent-nhibernate

我是第一次尝试FluentNHibernate AutoPersistenceModel。得到一个基本的例子非常简单,但我遇到了一个问题,使它适合我的工作方式。我通常使用接口,以便我的实体都实现一个接口并通过它们的接口引用所有相关实体,而不是它们的具体类型。鉴于以下类别:

public Interface IFoo { }

public Interface IBar { IFoo Foo { get; set; } }

public Class Foo : IFoo { }

public Class Bar : IBar
{
     public IFoo Foo { get; set; }
}

我会有以下映射:

public class BarMapping : ClassMap<Bar>
{
    public AnswerMapping()
    {
        References<Foo>( x => x.Foo ).Column( "FooId" ).Cascade.None();
    }
}

我如何使用AutoPersistenceModel实现相同的目标?我简要介绍了约定和ReferenceConvention构建器,但没有任何文档或示例,我一直在挣扎。

修改

我现在将其与我的其他SO post一起转换为集合映射到博客帖子的接口: http://bronumski.blogspot.com/2011/01/making-fluent-nhibernate-automapper.html

1 个答案:

答案 0 :(得分:1)

经过一番挖掘后,我想出了一个解决方案。我已经看到过在其他示例中使用的IReferenceConvention接口,但不包括此场景。通过实现接口并执行自定义约定,我已经能够使用与ClassMap相同的AutoPersistenceModel实现相同的功能。

public class ReferenceConvention : IReferenceConvention
{
    public void Apply(IManyToOneInstance instance)
    {
        Type instanceType = instance.Class.GetUnderlyingSystemType();
        if (instanceType == typeof(IFoo))
        {
            instance.CustomClass<Foo>();
        }

        instance.Cascade.All();
    }
}

更通用的方法可能是:

public class ReferenceConvention : IReferenceConvention
{
    public void Apply(IManyToOneInstance instance)
    {
        Type instanceType = instance.Class.GetUnderlyingSystemType();

        if (instanceType.IsInterface)
        {
            // Assuming that the type starts with an I get the name of the concrete class
            string className = instanceType.Name.Substring( 1 );

            instance.CustomClass(instanceType.Assembly.GetType(
                instanceType.FullName.Replace( instanceType.Name, className )));
        }

        instance.Cascade.All();
    }
}

还有一个我还没有看过的ReferenceConventionBuilder,但这可能是一个更清洁的解决方案。