流畅的 NHibernate DuplicateMappingException 与 AutoMapping

发布于 2024-08-01 22:45:37 字数 1598 浏览 9 评论 0原文

摘要:

我想使用 Fluent NHibernate Automapper 保存两个具有相同名称和不同名称空间的类

Context

我正在编写,必须将许多不同的对象导入到数据库中测试。 我最终会将映射器编写为适当的模型。

我一直在使用 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

Summary:

I want to save two classes of the same name and different namespaces with the Fluent NHibernate Automapper

Context

I'm writing having to import a lot of different objects to database for testing. I'll eventually write mappers to a proper model.

I've been using code gen and Fluent NHibernate to take these DTOs and dump them straight to db.

the exception does say to (try using auto-import="false")

Code

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; }        
    }
}

And here's the actual app code

            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);

Thanks I really appreciate any help

Update using Fluent Nhibernate RC1

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

两个我 2024-08-08 22:45:38

我无法使用 FluentMappings 的约定(与 AutoMappings 相比)来实现这一点。 但是,以下内容对我有用,但必须在需要时将其添加到每个 ClassMap 中。

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

I was not able to get this to work using Conventions for FluentMappings (in contrast to AutoMappings). However, the following works for me, though it must be added to each ClassMap where needed.

public class AMap : ClassMap<A> 
{
    public AMap()
    {
        HibernateMapping.Not.AutoImport();
        Map(x => x.Item, "item");
        ...
    }
}
傾城如夢未必闌珊 2024-08-08 22:45:38

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

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 ,但没​​有成功。

我可以提供一些关于如何执行此操作的更广泛的示例吗?

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

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

I am having real problem with this, and the example above or any of its variants do not help.

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();

I can't find Program's reference..

I've also tried to put down a seperate xml file to in desperation config fluent nhibernate's mapping to auto-import = false with no success.

Can I please have some more extensive example on how to do this?

Edit, I got the latest trunk just weeks ago.

Edit, Solved this by removing all duplicates.

菊凝晚露 2024-08-08 22:45:38

我曾经也有过一样的问题。 我这样解决了:

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()))。 使用此配置一切似乎都工作正常。

I have had the same problem. I solved it like this:

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

The imported part is: .Conventions.Setup(x => x.Add(AutoImport.Never())). Everything seems to be working fine with this configuration.

岁月打碎记忆 2024-08-08 22:45:38

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

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

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

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

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

Use the BeforeBindMapping event to gain access to the object representation of the .HBM XML files.

This event allows you to modify any properties at runtime before the NHibernate Session Factory is created. This also makes the FluentNHibernate-equivalent convention unnecessary. Unfortunately there is currently no official documentation around this really great feature.

Here's a global solution to duplicate mapping problems ( Just remember that all HQL queries will now need to use Fully Qualified Type names instead of just the class names ).

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

configuration.BeforeBindMapping += (sender, args) => args.Mapping.autoimport = false;
墨离汐 2024-08-08 22:45:38

我必须考虑在哪里添加约定 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()) 添加到每个持久性映射器中,它的工作方式就像一个魅力。

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

I had to play around with where to add the convention AutoImport.Never() to. I have my persistence mapping separated into different projects - models for each application can also be found in different projects. Using it with Fluent NHibernate and auto mapping.

There are occasions when domains, well mappings really have to be combined. This would be when I need access to all domains. POCO classes used will sometimes have the same name and different namespaces, just as examples above.

Here is how my combine all mapping looks like:

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();
    }
}

And one of the persistence mappers:

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>();
    }
}

Persistence mappers are very similar for each POCO namespace - some have overrides. I had to add .Conventions.Add(AutoImport.Never()) to each persistence mapper and it works like a charm.

Just wanted to share this if anyone else is doing it this way.

冰葑 2024-08-08 22:45:37

James Gregory 的来自 Fluent-nhibernate 论坛的解决方案

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

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

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

solution from fluent-nhibernate forums by James Gregory

Got around to having a proper look at
this tonight. Basically, it is down to
the AutoImport stuff the exception
mentioned; when NHibernate is given
the first mapping it sees that the
entity is named with the full assembly
qualified name and creates an import
for the short name (being helpful!),
and then when you add the second one
it then complains that this import is
now going to conflict. So the solution
is to turn off the auto importing;
unfortunately, we don't have a way to
do that in the RC... I've just
commited a fix that adds in the
ability to change this in a
convention. So if you get the latest
binaries or source, you should be able
to change your Conventions line in
your attached project to do this:

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

Which adds all the conventions you've
defined in your assembly, then uses
one of the helper conventions to turn
off auto importing.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文