如何使用流畅的非hibernate自动映射来引用同一表中的父实体
本文关键字:引用 实体 何使用 hibernate 映射 | 更新日期: 2023-09-27 18:03:57
我试图使用FluentNHibernate automapping来创建一个引用其父实体。我能够在ClassMap<>的帮助下做到这一点,但现在我想将所有内容移动到automapping。我有一个模式如下的表:
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:Job [JobId, ParentId]))必须与引用的主键(Job [Id])具有相同的列数
是否有一种方法只使用自动映射来做到这一点?
您的DefaultReferenceConvention
似乎与您的SimpleForeignKeyConvention
冲突。其中一个使用属性名称作为列名的基础,另一个使用属性类型。看起来出于某种原因,Fluent NH同时使用了和,并认为您有一个复合键。
删除DefaultReferenceConvention
,看看是否修复它。这是不必要的,因为Fluent NH的默认外键列命名已经是{Class.Name}Id
了。
流畅的NH约定非常适合用粗笔触绘制映射,但它们不是更改单个属性的列名的正确工具。在这种情况下,应该定义一个IAutoMappingOverride<T>
。