簡體   English   中英

如何使用流暢的nhibernate自動映射在同一個表中引用父實體?

[英]How to reference parent entity in the same table with fluent nhibernate auto mappings?

我正在嘗試使用FluentNHibernate AutoMappings來創建一個引用其父級的實體。 我能夠在ClassMap <>的幫助下做到這一點,但現在我想把所有東西都移到AutoMappings。 我有一個包含以下架構的表:

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

我正進入(狀態:

創建SessionFactory時使用了無效或不完整的配置。 檢查PotentialReasons集合,以及InnerException以獲取更多詳細信息。

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

有沒有辦法只使用自動映射?

您的DefaultReferenceConvention似乎與您的SimpleForeignKeyConvention沖突。 其中一個使用屬性名稱作為列名稱的基礎,另一個使用屬性類型 看起來由於某種原因,Fluent NH正在使用這兩者 ,並認為你有一個復合鍵。

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

流暢的NH約定非常適合使用寬泛的筆觸繪制映射,但它們不是更改單個屬性的列名稱的正確工具。 在這種情況下,您應該定義IAutoMappingOverride<T>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM