我正在创建一个Fluent N休眠子类映射,该映射目前看起来像这样:
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”,这样我就可以遵循我的命名约定。
您无法使用fluent API配置子类ID,因为它是由内置的映射连接处理的。但是您可以编写自定义约定(如果需要,可以接受一些额外的约定)。 样本解决方案:
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>(); });