【问题标题】:Fluent NHibernate DuplicateMappingException with AutoMappingFluent NHibernate DuplicateMappingException 与 AutoMapping
【发布时间】:2009-08-17 21:09:31
【问题描述】:

总结:

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

上下文

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

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

异常确实表明(尝试使用 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

【问题讨论】:

  • 将我的代码更新到 Fluent NHibernate RC1

标签: mysql fluent-nhibernate automapping


【解决方案1】:

solution from fluent-nhibernate forums 詹姆斯·格雷戈里

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

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

它添加了您已添加的所有约定 在您的程序集中定义,然后使用 要转的助手约定之一 关闭自动导入。

【讨论】:

    【解决方案2】:

    我无法使用 FluentMappings 的约定(与 AutoMappings 相比)使其工作。但是,以下内容对我有用,尽管它必须在需要的地方添加到每个 ClassMap 中。

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

    【讨论】:

    • HibernateMapping.Not.AutoImport(); 使用了哪些导入?当我使用上述示例时,我收到一条消息,指出 FluentNHibernate.MappingModel.HibernateMapping 不包含 Not error 的定义。
    • code 使用 FluentNHibernate;使用 FluentNHibernate.MappingModel;使用 FluentNHibernate.Mapping; code Intellisense 显示 Not 是 HibernateMappingPart 的成员。这适用于 FluentNHibernate 1.2。
    • 这种方法在我的情况下有效!我只有项目中 1 个重复类映射的来源。副本来自使用 NuGet 引用的程序集。我将 Not.AutoImport() 添加到 1 类并修复了它。
    【解决方案3】:

    我遇到了真正的问题,上面的示例或其任何变体都没有帮助。

    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 文件放入绝望的配置 fluent nhibernate 到 auto-import = false 的映射,但没有成功。

    我可以举一些更广泛的例子来说明如何做到这一点吗?

    编辑,几周前我拿到了最新的行李箱。

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

    【讨论】:

      【解决方案4】:

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

      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 =&gt; x.Add(AutoImport.Never()))。使用此配置似乎一切正常。

      【讨论】:

        【解决方案5】:

        使用BeforeBindMapping 事件获取对 .HBM XML 文件的对象表示的访问权限。

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

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

        var configuration = new NHibernate.Cfg.Configuration();
        
        configuration.BeforeBindMapping += (sender, args) => args.Mapping.autoimport = false;
        

        【讨论】:

        • 我在我的项目上试过这个,但它对解决错误没有任何影响。
        【解决方案6】:

        我不得不考虑将约定 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()) 添加到每个持久性映射器,它就像一个魅力。

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-11-25
          • 1970-01-01
          • 1970-01-01
          • 2010-10-09
          • 1970-01-01
          • 1970-01-01
          • 2011-12-10
          • 1970-01-01
          相关资源
          最近更新 更多