如何使用Fluent nHibernate配置多个映射?

时间:2010-03-25 14:54:54

标签: nhibernate fluent-nhibernate

第一次用NHibernate / Fluent摇滚它,如果这是一个天真的问题,请提前道歉。我有一组我要映射的模型。当我创建会话工厂时,我正在尝试立即执行所有映射。我没有使用自动映射(尽管如果我想要做的事情最终会比它应该更痛苦)。我遇到的问题是,似乎只有顶级地图正在采取。鉴于下面的代码片段并运行单元测试试图保存'bar',它失败并检查日志我看到NHibernate试图将一个条实体保存到foo表。虽然我怀疑它是我的映射,但它可能是我忽略的其他东西。

创建会话工厂的代码(注意我还尝试过单独调用.Mappings):

Fluently.Configure().Database(MsSqlConfiguration.MsSql2008
    .ConnectionString(c => c
        .Server(@"localhost\SQLEXPRESS")
        .Database("foo")
        .Username("foo")
        .Password("foo")))
    .Mappings(m => 
        { 
            m.FluentMappings.AddFromAssemblyOf<FooMap>()
                .Conventions.Add(FluentNHibernate.Conventions.Helpers
                .Table.Is(x => "foos"));
            m.FluentMappings.AddFromAssemblyOf<BarMap>()
                .Conventions.Add(FluentNHibernate.Conventions.Helpers
                .Table.Is(x => "bars"));
        })
    .BuildSessionFactory();

单元测试代码段:

using (var session = Data.SessionHelper.SessionFactory.OpenSession()) {      
   var bar = new Bar();
   session.Save(bar);
   Assert.NotNull(bar.Id);
}

3 个答案:

答案 0 :(得分:2)

你做错了。 :)

首先,m.FluentMappings.AddFromAssemblyOf<FooMap>()m.FluentMappings.AddFromAssemblyOf<BarMap>()执行完全相同的操作(如果FooMapBarMap在同一个程序集中)。每个人都告诉Fluent NHibernate扫描包含泛型类型的程序集;因此,如果两个类型都在同一个程序集中,它将扫描两次。

其次,Conventions调用的范围不是您之后调用的特定程序集,而是整个映射集。所以你要做的是提供两个约定来将表名设置为显式值,第二个是要应用的最后一个。你想要做的是使用x参数(这是实体类型)并从中创建你的表名。

你需要的是这样的东西:

.Mappings(m => 
{ 
  m.FluentMappings.AddFromAssemblyOf<FooMap>()
   .Conventions.Add(Table.Is(x => x.Name + "s"));
})

显然我的实现很幼稚,根据你的表命名约定,你可能想要使用复数(我相信Castle有一个,但是用google找一个并不难)。

您可以在conventions上阅读有关Fluent NHibernate wiki的更多信息。

答案 1 :(得分:0)

使用classmap,您可以在mapping中指定表名。如果未指定,则它将与实体类名称相同。

class FooMap : ClassMap<Foo>
{
    public FooMap()
    {
        Table("foos");
    }
}

Conventions适用于所有映射。当您添加了2个表名约定时,只有1个会生效。

你的FooMap和BarMap在同一个程序集中吗?您只需要添加一次组件。

.Mappings(m => m.FluentMappings.AddFromAssemblyOf<FooMap>())

答案 2 :(得分:0)

只想分享这个会自动添加基于结尾字母表的复数名称 s,es,ies。不太确定语法和一些例外,但这对我来说似乎没问题。任何使用Table("foos")的例外都像@Lachlan Roche说的那样。例如。 客户类会有客户表,类别类会有类别表。

修改后的@James Gregory回答:

.Mappings(m => 
{ 
  m.FluentMappings.AddFromAssemblyOf<FooMap>()
   .Conventions.Add(Table.Is(x => GetPluralName(x.Name));
})


public static string GetPluralName(string oldName)
{
    // This is the very simple. Just ignore exception like days, boys, photos and other specific nouns.
    if (oldName.EndsWith("y"))
        return oldName.Remove(oldName.Length - 1) + "ies";
    else if (oldName.EndsWith("s") || oldName.EndsWith("e") || oldName.EndsWith("h") || oldName.EndsWith("z") || oldName.EndsWith("o")) // Sibilant consonant or "o"
        return oldName + "es";
    return oldName + "s";
}