我正在创建一个Fluent N hibernate子类映射,目前看起来像这样:
public class TaskDownloadMap: SubclassMap<TaskDownload>
{
public TaskDownloadMap()
{
Table("TasksDownload");
Map(x => x.ExtraProperty1, "ExtraProperty1")
.Nullable();
Map(x => x.ExtraProperty2, "ExtraProperty2")
.Nullable();
}
}
当我尝试保存其中一个实体时,我得到一个例外:
Test.TaskRepositoryTest.DeleteTest:
NHibernate.Exceptions.GenericADOException : could not insert: [TaskManager.Entities.TaskDownload#269][SQL: INSERT INTO TasksDownload (ExtraProperty1, ExtraProperty2, Task_id) VALUES (?, ?, ?)]
----> System.Data.SqlClient.SqlException : Invalid column name 'Task_id'.
这是因为我在子类的表上设置的Id列被命名为“TaskId”。是否有一些覆盖nhibernate试图使用的默认命名方案?我似乎没有能力在子类中指定“Id”列,我甚至无法找到其他任何人。
父映射如下所示:
public class TaskMap: ClassMap<Task>
{
public TaskMap()
{
Table("Tasks");
Id(x => x.Id, "Id")
.GeneratedBy.Identity();
.
.
.
}
}
就像我之前所说的那样,我将使用Table-Per-Subclass策略,因此这些是2个不同的表。我可以将TasksDownload表上的键更改为“Task_id”,但我只能在映射中指定它是“TaskId”,这样我就可以遵守我的命名约定。
答案 0 :(得分:4)
您无法使用流畅的API配置子类ID,因为它由内置的映射对象处理。但是您可以编写自定义convention(如果需要,还可以添加一些acceptance) 样本解决方案:
public class JoinedSubclassIdConvention : IJoinedSubclassConvention,
IJoinedSubclassConventionAcceptance
{
public void Apply(IJoinedSubclassInstance instance)
{
instance.Key.Column(instance.EntityType.BaseType.Name + "Id");
}
public void Accept(IAcceptanceCriteria<IJoinedSubclassInspector> criteria)
{
criteria.Expect(x => x.EntityType == typeof(TaskDownload));
}
}
然后将您的对话添加到配置中:
Fluently.Configure()
//...
.Mappings(m =>
{
m.FluentMappings
//...
.Conventions.Add<JoinedSubclassIdConvention>();
});