Свободный NHibernate - как создать отображение таблицы на подкласс, используя дискриминатор? - PullRequest
2 голосов
/ 27 марта 2012

Я просмотрел множество вопросов по SO и google относительно отображений подклассов в nhibernate / fluent-nhibernate и не смог найти никого с такой же проблемой, как у меня.Я следовал основным инструкциям из вики fluent-nhibernate (http://wiki.fluentnhibernate.org/Fluent_mapping#Subclasses), но это не помогло.

У меня есть базовая сущность с именем Operation - с которой связана базовая таблица, затемвложенные таблицы UnpaidCheque, Refund и т. д. - первичным ключом для каждой из этих вложенных таблиц является внешний ключ, OperationId (PK) из таблицы операций.

Когда я создаю спецификацию постоянства и пытаюсь проверитьВ моих сопоставлениях он пытается сохранить все столбцы в таблице операций, а не сохранять в таблице операций, а затем сохранять определенные столбцы неоплаченной проверки в таблице UnpaidCheque.

Ошибка:

could not insert: [UnpaidCheque][SQL: INSERT INTO Account.Operation (PaymentId, Amount, UnpaidOn, UnpaidByUserId, OperationType) VALUES (?, ?, ?, ?, 'U'); select SCOPE_IDENTITY()]
  ----> System.Data.SqlClient.SqlException : Invalid column name 'UnpaidOn'.
Invalid column name 'UnpaidByUserId'.

Как видите, он пытается сохранить значения в столбцах UnpaidByUserId и UnpaidOn, которые являются членами вложенной таблицы / класса, а не базы.

С другой стороны, тот факт, что он пытаетсявставка 'U' в столбец operationtype указывает мне, что он, похоже, устанавливает правильное значение дескриптора для типа класса.Единственное место, где я указал тип операции, - это вызов DiscriminatorValue () на карте классов, я не устанавливаю его явно где-либо еще.

Иерархия классов выглядит следующим образом:

public class Operation
    {
        public virtual long OperationId { get; set; }
        public virtual string OperationType { get; set; }
        public virtual long? PaymentId { get; set; }
        public virtual decimal Amount { get; set; }
    }

public class UnpaidCheque : Operation
    {
        public virtual DateTime UnpaidOn { get; set; }
        public virtual long UnpaidByUserId { get; set; }
    }

Отображения классов:

public class OperationMap : ClassMap<Operation>
    {
        public OperationMap()
        {
            Schema("Account");
            Table("Operation");
            LazyLoad();
            Id(_ => _.OperationId).Column("OperationId").GeneratedBy.Identity();
            Map(_ => _.PaymentId).Column("PaymentId").Nullable();
            Map(_ => _.Amount).Column("Amount").Not.Nullable();

            DiscriminateSubClassesOnColumn("OperationType");
        }
    }
public class UnpaidChequeMap : SubclassMap<UnpaidCheque>
{
    public UnpaidChequeMap()
        {
            Schema("Account");
            Table("UnpaidCheque");
            LazyLoad();
            DiscriminatorValue("U");
            KeyColumn("OperationId");
            Map(_ => _.UnpaidOn).Column("UnpaidOn").Not.Nullable();
            Map(_ => _.UnpaidByUserId).Column("UnpaidByUserId").Not.Nullable();
        }
}

Я не вижу ничего, что я сделал иначе, чем пример, кроме добавления KeyColumn () в карту подкласса, однако я получаю то же сообщение об ошибке безэто также.Может кто-нибудь пролить свет на то, что я пропустил, или если то, чего я пытаюсь достичь, поддерживается nhibernate?Насколько я могу сказать, это должно быть.

Заранее спасибо!

Ответы [ 2 ]

2 голосов
/ 27 января 2017

Для использования таблицы на подкласс С Дискриминатором работают следующие:

public class UnpaidChequeMap : SubclassMap<UnpaidCheque>
{
    public UnpaidChequeMap()
    {
        Schema("Account");
        DiscriminatorValue("U");
        Join("UnpaidCheque", j =>
        {
            j.KeyColumn("OperationId");
            j.Map(_ => _.UnpaidOn).Column("UnpaidOn").Not.Nullable();
            j.Map(_ => _.UnpaidByUserId).Column("UnpaidByUserId").Not.Nullable();
        }
    }
}
1 голос
/ 27 марта 2012

Мы нашли решение:

Описатели предназначены только для отображений, где все подклассы хранятся в одной таблице в базе данных.

Удаление строк:

DiscriminateSubClassesOnColumn("OperationType");

из родительского сопоставления и

DiscriminatorValue("U");

из дочернего сопоставления, а затем удаление столбца из базы данных решило проблему.

...