Можете ли вы указать столбец идентификации при использовании стратегии Fluent Nhibernate Table-Per-Subclass? - PullRequest
7 голосов
/ 03 февраля 2012

Я создаю отображение подкласса спящего 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, так что это две разные таблицы. Я могу изменить ключ в моей таблице TasksDownload на «Task_id», но я бы предпочел просто указать, что это «TaskId» в моем отображении, чтобы я мог придерживаться моего соглашения об именах.

1 Ответ

4 голосов
/ 03 февраля 2012

Вы не можете сконфигурировать идентификаторы подкласса с плавным API, потому что он обрабатывается встроенными соглашениями отображения. Но вы можете написать пользовательское соглашение (с дополнительным принятием , если требуется).
Пример решения:

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>();
        });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...