2009-08-17 262 views
4

摘要:功能NHibernate DuplicateMappingException與自動映射

我要救兩個類相同的名稱和不同的命名空間與功能NHibernate Automapper

語境

我在寫有將大量不同的對象導入數據庫進行測試。我最終會將映射器寫入適當的模型。

我一直在使用代碼gen和流利NHibernate採取這些DTOs並將它們直接轉儲到分貝。

異常不說(請嘗試使用自動導入= 「假」)

代碼

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

謝謝我非常感謝任何幫助

更新使用功能NHibernate RC1

+0

更新我的代碼到Fluent NHibernate RC1 – 2009-08-17 21:32:51

回答

7

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

長出一圈今晚有一個適當的看 。基本上,這是自動進口的東西 提到的例外 ;當NHibernate的被賦予 第一映射它看到的 實體命名與全裝配 合格的名稱和短名稱創建一個進口 (是有幫助的!), 然後當你添加第二個 它,然後抱怨現在這個進口是 會發生衝突。所以解決方案 是關閉自動導入; 不幸的是,我們沒有辦法通過 做到這一點在RC ...我只是 提出了一個修復,增加了 能力來改變這在 公約。所以,如果你獲得最新 二進制文件或源,你應該能夠 改變你的約定行 你連接的項目要做到這一點:

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

它增加了所有你已經 公約在您的程序集中定義,然後使用 輔助約定之一將 關閉自動導入。

+0

此建議也適用於非自動映射。 – ddc0660 2009-12-21 21:12:58

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的映射放下在絕望中配置以自動導入=沒有成功虛假。

請問我有關於如何做到這一點的更廣泛的例子?

編輯,我幾個星期前得到了最新的主幹。

編輯,解決這個通過刪除所有重複。

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()))。一切似乎都與這種配置工作正常。

6

我無法使用FluentMappings慣例(與AutoMappings相比)使用此約定。不過,下面的代碼適用於我,儘管它必須添加到每個需要的ClassMap中。

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

你使用了什麼導入'HibernateMapping.Not.AutoImport();'?當我使用上面的示例時,我收到一條消息,指出FluentNHibernate.MappingModel.HibernateMapping不包含「錯誤」的定義。使用FluentNHibernate的'code'使用 – ahsteele 2011-11-21 18:40:11

+0

; using FluentNHibernate.MappingModel; using FluentNHibernate.Mapping; 'code' Intellisense顯示Not是HibernateMappingPart的成員。這是針對FluentNHibernate 1.2的。 – 2012-01-10 17:44:45

0

使用BeforeBindMapping事件來獲得對.HBM XML文件的對象表示。

此事件允許您在創建NHibernate會話工廠之前修改運行時的任何屬性。這也使得FluentNHibernate相當於約定是不必要的。不幸的是,目前還沒有關於這個真棒功能的官方文檔。

這是一個複製映射問題的全局解決方案(請記住,所有HQL查詢現在需要使用完全限定類型名稱而不僅僅是類名稱)。

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

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

我不得不玩弄添加慣例AutoImport.Never()到的位置。我將持久性映射分爲不同的項目 - 每個應用程序的模型也可以在不同的項目中找到。使用它與流利的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(); 
    } 
} 

和Persistence映射器之一:

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())到每個持久性映射器,它的工作方式就像一個魅力。

只是想分享這個,如果其他人這樣做。