2010-03-12 28 views
0

我試圖使用流暢的自動映射功能爲以下模型和程序生成 DDL,但不知何故,我總是收到 錯誤「關聯引用未映射的類:IRole「,當我在NHibernate中調用 GenerateSchemaCreationScript方法時。當我用接口的實現(用戶 和角色)替換 ILists的類型時,一切正常。我在這裏做錯了什麼?我如何可以流利地使用在Unity中定義的 實現的IUser和IRole版本?當在模型中使用接口時出現錯誤「關聯引用未映射的類」

public interface IRole 
{ 
    string Title { get; set; } 
    IList<IUser> Users { get; set; } 
} 

    public interface IUser 
    { 
     string Email { get; set; } 
     IList<IRole> Roles { get; set; } 
    } 

public class Role : IRole 
{ 
    public virtual string Title { get; set; } 
    public virtual IList<IUser> Users { get; set; } 
} 
public class User : IUser 
{ 
    public virtual string Email { get; set; } 
    public virtual IList<IRole> Roles { get; set; } 
} 

我用下面的程序來生成NHibernate的使用 GenerateSchemaCreationScript的DDL:

class Program 
{ 
    static void Main(string[] args) 
    { 
     var ddl = new NHibernateSessionManager(); 
     ddl.BuildConfiguration(); 
    } 
} 

    public class NHibernateSessionManager 
    { 
     private ISessionFactory _sessionFactory; 
     private static IUnityContainer _container; 

     private static void InitContainer() 
     { 
      _container = new UnityContainer(); 
      _container.RegisterType(typeof(IUser), typeof(User)); 
      _container.RegisterType(typeof(IRole), typeof(Role)); 
     } 

     public ISessionFactory BuildConfiguration() 
     { 
      InitContainer(); 
      return 
Fluently.Configure().Database(MsSqlConfiguration.MsSql2008 
       .ConnectionString("ConnectionString")) 
       .Mappings(m => m.AutoMappings.Add(
        AutoMap.AssemblyOf<IUser>())) 
       .ExposeConfiguration(BuildSchema) 
       .BuildSessionFactory(); 
     } 

     private void BuildSchema(Configuration cfg) 
     { 
      var ddl = cfg.GenerateSchemaCreationScript(new 
NHibernate.Dialect.MsSql2008Dialect()); 
      System.IO.File.WriteAllLines("Filename", ddl); 
     } 

    } 

回答

0

你不能提供一個接口作爲類型T在AssemblyOf<T>,您需要提供一個具體的類型。或者你可以使用一個接受assemply方法:

.Mappings(m => m.AutoMappings.Add(
       AutoMap.Assembly(myAssembly))) 

編輯:問題是你的類包含接口類型,而不是類類型的集合。我不知道是否有可能以這種方式自動映射接口。另外,我認爲使用接口來指定域對象幾乎沒有任何價值。

+0

比較遺憾的是 - 它當然應該是: .Mappings(M = > m.AutoMappings.Add( AutoMap.AssemblyOf ())) 但我的問題仍然是一樣的,我得到的錯誤: 公共虛擬IList 用戶{get;組; } 和 公共虛擬IList 角色{get;組; } 任何想法如何解決這個問題? – Bjarke 2010-03-15 08:15:42

+0

查看編輯到我原來​​的答案。 – 2010-03-15 12:08:55

+0

根據http://steve-fair-dev.blogspot.com/2009/10/nhibernate-entity-property-is-interface.html有可能告訴NHibernate它應該爲接口使用哪種實現(使用映射 - 文件)。我只是想知道是否有辦法讓Fluent的automapping知道同樣的事情? – Bjarke 2010-03-16 10:14:00

1

我和你情況一樣。在使用ClassMap之前,我知道你可以用Fluent做到這一點,但之前我從未使用AutoMapping功能。我已經成功地使用IReferenceConvention與AutoMapper進行一對一的映射(請參閱前面的SO post)。

我現在遇到了同樣的問題,因爲我有一對多的映射,我現在遇到了問題。有一個我已經開始關注的IHasManyConvention界面,但迄今還沒有運氣。

僅僅因爲有些事情很難做到這一點並不會造成錯誤,所以映射到接口上有一定的價值,可以在原始nHibernate映射文件中或通過使用Fluentnts ClassMap映射文件輕鬆完成。我認爲一旦人們開始使用AutoMapping功能做更多的事情,就會有更多的博客文章。

編輯

我發現使用IAutoMappingOverride的臨時解決方案。以下是您需要的一個粗略示例。

public class RoleAutoMappingOverride : IAutoMappingOverride<Role> 
{ 
    public void Override(AutoMapping<Role> mapping) 
    { 
     mapping.HasMany<User>(x => x.Users).KeyColumn("User_id"); 
    } 
} 

編輯

我的一位大學已制定了使用,而不是替代約定一個更好的解決方案。這涵蓋了如何做一個單一的類,但如果你看看我之前提到的SO帖子,你可以看到如何做到這一點。

public class Foo : IHasManyConvention 
{ 
    public void Apply(IOneToManyCollectionInstance instance) 
    { 
     if (instance.ChildType == typeof(Role)) 
     { 
      instance.Relationship.CustomClass<User>(); 
     } 
    } 
} 

編輯

我現在已經把這個和我的其他後進入的博客文章: http://bronumski.blogspot.com/2011/01/making-fluent-nhibernate-automapper.html

相關問題