3

我正在嘗試使用FluentNHibernate AutoMappings來創建一個參考其父項的實體。我可以在ClassMap <>的幫助下做到這一點,但現在我想將所有內容都移動到AutoMappings。我有以下架構表:如何使用流暢的nhibernate自動映射引用同一個表中的父實體?

CREATE TABLE [dbo].[Job] 
(
    [Id] INT NOT NULL IDENTITY(1,1), 
    [ParentId] INT NULL, 
    PRIMARY KEY ([Id]), 
    CONSTRAINT [FK_Job_Parent] FOREIGN KEY ([ParentId]) REFERENCES [Job]([Id]) 
) 

而下面的C#代碼:

using FluentNHibernate; 
using FluentNHibernate.Automapping; 
using FluentNHibernate.Cfg; 
using FluentNHibernate.Cfg.Db; 
using FluentNHibernate.Conventions; 
using FluentNHibernate.Conventions.Instances; 
using System; 
using System.Configuration; 

namespace NHibernateTest 
{ 
    public class Program 
    { 
     private static void Main(string[] args) 
     { 
      var sessionFactory = Fluently.Configure() 
       .Database(MsSqlConfiguration.MsSql2008.ConnectionString(ConfigurationManager.ConnectionStrings["Default"].ConnectionString)) 
       .Mappings(m => 
       { 
        m.AutoMappings.Add(
         AutoMap.AssemblyOf<Program>(new MappingConfig()).Conventions.Setup(conv => 
        { 
         conv.Add<DefaultReferenceConvention>(); 
         conv.Add<DefaultHasManyConvention>(); 
         conv.Add<SimpleForeignKeyConvention>(); 
        })); 
       }) 
       .BuildSessionFactory(); 

      using (var session = sessionFactory.OpenSession()) 
      { 
       using (var tran = session.BeginTransaction()) 
       { 
        var jobs = session 
         .QueryOver<Job>() 
         .List<Job>(); 

        tran.Commit(); 
       } 
      } 
     } 
    } 

    public class Job 
    { 
     public virtual int Id { get; set; } 

     public virtual Job Parent { get; set; } 
    } 

    public class MappingConfig : DefaultAutomappingConfiguration 
    { 
     public override bool ShouldMap(Type type) 
     { 
      return type == typeof(Job); 
     } 
    } 

    public class SimpleForeignKeyConvention : ForeignKeyConvention 
    { 
     protected override string GetKeyName(Member property, Type type) 
     { 
      if (property == null) 
      { 
       return type.Name + "Id"; 
      } 

      return property.Name + "Id"; 
     } 
    } 

    public class DefaultHasManyConvention : IHasManyConvention 
    { 
     public void Apply(IOneToManyCollectionInstance instance) 
     { 
      instance.Key.Column(string.Format("{0}{1}", instance.EntityType.Name, "Id")); 
      instance.LazyLoad(); 
     } 
    } 

    public class DefaultReferenceConvention : IReferenceConvention 
    { 
     public void Apply(IManyToOneInstance instance) 
     { 
      var col = string.Format("{0}Id", instance.Class.Name); 
      instance.Column(col); 
      instance.LazyLoad(); 
     } 
    } 
} 

我越來越:

是在創建一個會話使用了無效的或不完整的配置。請參閱PotentialReasons集合和InnerException以獲取更多詳細信息。

外鍵(FK7D5D63A6AE42E0BA:作業[的JobId,的ParentId]))必須有相同數量的被引用的主鍵列(作業[ID])

有沒有辦法做到這一點使用自動映射只要?

回答

0

您的DefaultReferenceConvention似乎與您的SimpleForeignKeyConvention發生衝突。其中一個使用屬性名稱作爲列名的依據,另一個使用屬性類型。看起來由於某種原因,Fluent NH使用這兩個都是,並且認爲你有一個複合鍵。

刪除DefaultReferenceConvention看看是否修復它。無論如何,這是不必要的,因爲Fluent NH的默認外鍵列命名已經是{Class.Name}Id

流利的NH慣例非常適合用廣泛的筆觸描畫您的映射,但它們不是更改單個屬性的列名稱的正確工具。在這種情況下,您應該定義一個IAutoMappingOverride<T>

相關問題