我正在创建一个Fluent N hibernate子类映射,目前看起来像这样:
@H_403_2@public class TaskDownloadMap: SubclassMap<TaskDownload>
{
public TaskDownloadMap()
{
Table("TasksDownload");
Map(x => x.ExtraProperty1,"ExtraProperty1")
.Nullable();
Map(x => x.ExtraProperty2,"ExtraProperty2")
.Nullable();
}
}
当我尝试保存其中一个实体时,我得到一个例外:
@H_403_2@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”列,我甚至无法找到其他任何人谈论它.
父映射如下所示:
@H_403_2@public class TaskMap: ClassMap<Task> { public TaskMap() { Table("Tasks"); Id(x => x.Id,"Id") .GeneratedBy.Identity(); . . . } }就像我之前所说的那样,我将使用Table-Per-Subclass策略,因此这些是2个不同的表.我可以将TasksDownload表上的键更改为“Task_id”,但我宁愿能够在映射中指定它是“TaskId”,这样我就可以遵循我的命名约定.
解决方法
您无法使用流畅的API配置子类ID,因为它由内置的映射对象处理.但是你可以编写一个自定义
convention(如果需要的话还有一些额外的
acceptance).
样本解决方案: @H_403_2@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)); } }
样本解决方案: @H_403_2@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)); } }
然后将您的对流添加到配置中:
@H_403_2@Fluently.Configure() //... .Mappings(m => { m.FluentMappings //... .Conventions.Add<JoinedSubclassIdConvention>(); });