使用AutoMapping流畅的NHibernate DuplicateMappingException

时间:2009-08-17 21:09:31

标签: mysql fluent-nhibernate automapping

要点:

我想用Fluent NHibernate Automapper保存两个同名和不同命名空间的类

上下文

我写的是必须将许多不同的对象导入数据库进行测试。我最终会将mappers写成一个合适的模型。

我一直在使用code gen和Fluent NHibernate来获取这些DTO并将它们直接转储到数据库。

异常确实对(尝试使用auto-import =“false”)

代码

public class ClassConvention : IClassConvention
{
    public void Apply(IClassInstance instance)
    {
        instance.Table(instance.EntityType.Namespace.Replace(".", "_"));
    }
}

namespace Sample.Models.Test1
{
    public class Test
    {
        public virtual int Id { get; set; }
        public virtual string Something { get; set; }
    }
}

namespace Sample.Models.Test2
{
    public class Test
    {
        public virtual int Id { get; set; }
        public virtual string SomethingElse { get; set; }        
    }
}

这是实际的应用代码

            var model = AutoMap.AssemblyOf<Service1>()
                .Where(t => t.Namespace.StartsWith("Sample.Models"))
                .Conventions.AddFromAssemblyOf<Service1>();
            var cfg = Fluently.Configure()
                .Database(
                MySQLConfiguration.Standard.ConnectionString(
                    c => c.Is("database=test;server=localhost;user id=root;Password=;")))
                .Mappings(m => m.AutoMappings.Add(model))
                .BuildConfiguration();
            new SchemaExport(cfg).Execute(false, true, false);

谢谢,我非常感谢任何帮助

使用Fluent Nhibernate RC1

更新

6 个答案:

答案 0 :(得分:7)

James Gregory的

solution from fluent-nhibernate forums

  

好好看看   今晚。基本上,它是由   AutoImport填充异常   提及;什么时候给NHibernate   它看到的第一个映射   实体以完整程序集命名   限定名称并创建导入   为短名称(有帮助!),   然后当你添加第二个   然后它抱怨这个导入是   现在要发生冲突了。所以解决方案   是关闭自动导入;   不幸的是,我们没办法   在RC中这样做......我只是   提交了一个补充的补丁   能够改变这一点   惯例。所以,如果你得到最新的   二进制文件或源代码,你应该可以   更改您的约定行   您附加的项目:

.Conventions.Setup(x =>  {   
  x.AddFromAssemblyOf<Program>();   
  x.Add(AutoImport.Never());  }); 
  

这增加了你所有的约定   在你的程序集中定义,然后使用   转向的助手惯例之一   关闭自动导入。

答案 1 :(得分:6)

我无法使用FoursMappings的约定(与AutoMappings相比)。但是,以下内容适用于我,但必须将其添加到每个需要的ClassMap中。

public class AMap : ClassMap<A> 
{
    public AMap()
    {
        HibernateMapping.Not.AutoImport();
        Map(x => x.Item, "item");
        ...
    }
}

答案 2 :(得分:0)

我遇到了这个问题,上面的示例或其任何变体都无济于事。

var cfg = new NotifyFluentNhibernateConfiguration();

    return Fluently.Configure()
      .Database(
       FluentNHibernate.Cfg.Db.MsSqlConfiguration.MsSql2005
            .ConnectionString("Server=10.2.65.227\\SOSDBSERVER;Database=NotifyTest;User ID=NHibernateTester;Password=test;Trusted_Connection=False;")
      )

      .Mappings(m => {
          m.AutoMappings
            .Add(AutoMap.AssemblyOf<SubscriptionManagerRP>(cfg));
          m.FluentMappings.Conventions.Setup(x =>
          {
              x.AddFromAssemblyOf<Program>();
              x.Add(AutoImport.Never());
          });
      } )

      .BuildSessionFactory();

我找不到程序的参考..

我还试图在绝望中放下一个单独的xml文件。配置流畅的nhibernate映射到auto-import = false但没有成功。

我可以请一些关于如何做到这一点的更广泛的例子吗?

编辑,几周前我收到了最新的主干。

编辑,通过删除所有重复项解决此问题。

答案 3 :(得分:0)

我遇到了同样的问题。我这样解决了:

Fluently.Configure()
        .Database(MsSqlConfiguration.MsSql2008
            .ConnectionString(...)
            .AdoNetBatchSize(500))
        .Mappings(m => m.FluentMappings
            .Conventions.Setup(x => x.Add(AutoImport.Never()))
            .AddFromAssembly(...)
            .AddFromAssembly(...)
            .AddFromAssembly(...)
            .AddFromAssembly(...))
        ;

导入的部分是:.Conventions.Setup(x => x.Add(AutoImport.Never()))。这种配置似乎一切正常。

答案 4 :(得分:0)

使用BeforeBindMapping事件来访问.HBM XML文件的对象表示。

此事件允许您在创建NHibernate会话工厂之前在运行时修改任何属性。这也使得FluentNHibernate等效约定变得不必要。不幸的是,目前还没有关于这个非常棒的功能的官方文档。

这是复制映射问题的全局解决方案(请记住,所有HQL查询现在都需要使用完全限定类型名称而不仅仅是类名称。)

var configuration = new NHibernate.Cfg.Configuration();

configuration.BeforeBindMapping += (sender, args) => args.Mapping.autoimport = false;

答案 5 :(得分:0)

我不得不四处游说将AutoImport.Never()的约定添加到。我将持久性映射分成不同的项目 - 每个应用程序的模型也可以在不同的项目中找到。将它与Fluent NHibernate和自动映射一起使用。

有时候域名,井映射真的必须结合起来。这将是我需要访问所有域的时候。使用的POCO类有时会具有相同的名称和不同的名称空间,就像上面的示例一样。

以下是我的组合所有映射的样子:

internal static class NHIbernateUtility
{
    public static ISessionFactory CreateSessionFactory(string connectionString)
    {
        return Fluently.Configure()
            .Database(
                MsSqlConfiguration
                    .MsSql2008
                    .ConnectionString(connectionString))
            .Mappings(m => m.AutoMappings
                .Add(ProjectA.NHibernate.PersistenceMapper.CreatePersistenceModel()))
            .Mappings(m => m.AutoMappings
                .Add(ProjectB.NHibernate.PersistenceMapper.CreatePersistenceModel()))
            .Mappings(m => m.AutoMappings
                .Add(ProjectC.NHibernate.PersistenceMapper.CreatePersistenceModel())).BuildSessionFactory();
    }
}

其中一个持久性映射器:

public static class PersistenceMapper
{
    public static AutoPersistenceModel CreatePersistenceModel()
    {
        return
            AutoMap.AssemblyOf<Credential>(new AutoMapConfiguration())
                .IgnoreBase<BaseEntity>()
                .Conventions.Add(AutoImport.Never())
                .Conventions.Add<TableNameConvention>()
                .Conventions.Add<StandardForeignKeyConvention>()
                .Conventions.Add<CascadeAllConvention>()
                .Conventions.Add<StandardManyToManyTableNameConvention>()
                .Conventions.Add<PropertyConvention>();
    }
}

持久性映射器对于每个POCO命名空间非常相似 - 有些具有覆盖。我不得不将.Conventions.Add(AutoImport.Never())添加到每个持久性映射器中,它就像一个魅力。

如果其他人这样做的话,只是想分享一下。