Свободный NHibernate - отображение сущности как другого типа - PullRequest
1 голос
/ 01 сентября 2010

У меня есть класс, который я хотел бы отобразить как компонент на любую таблицу, в которой он содержится:

public class Time
{
    public int Hours { get; set; }
    public int Minutes { get; set; }
    public int Seconds { get; set; }
}

Я хотел бы сохранить этот класс как bigint в базе данных - так же, как хранится TimeSpan, но у моего класса совершенно другое поведение, поэтому я решил создать свой собственный.

Я использую автомаппер FLH, и этот класс установлен как компонент (другие классы имеют Time в качестве свойства). Я дошел до создания переопределения, но не уверен, как это сделать:

Я попробовал вот так:

public class TimeMappingOverride : IAutoMappingOverride<Time>
{
    public void Override(AutoMapping<Time> mapping)
    {
        mapping.Map(x => x.ToTimeSpan());
        mapping.IgnoreProperty(x => x.Hours);
        mapping.IgnoreProperty(x => x.Minutes);
        mapping.IgnoreProperty(x => x.Seconds);
    }
}

Но получил эту ошибку:

Невозможно привести объект типа 'System.Linq.Expressions.UnaryExpression' к типу 'System.Linq.Expressions.MethodCallExpression'.

Как мне поступить об этом?

Ответы [ 2 ]

2 голосов
/ 01 сентября 2010

Детали компонентов можно найти здесь: http://wiki.fluentnhibernate.org/Fluent_mapping#Components

Но, прежде всего, вы не можете сопоставить метод.

Если вы измените ToTimeSpan() на свойство AsTimeSpan, есть два способа сделать это, только самый сложный из которых будет работать для вас, потому что вы используете autopping:

  1. Создайте ComponentMap<Time> - когда закончите, ваше существующее отображение будет работать.Это несовместимо с автоматическим сопоставлением.
  2. Объявите сопоставление компонентов встроенным:
mapping.Component(x => x.AsTimeSpan, component => {  
    component.Map(Hours);  
    component.Map(Minutes);  
    component.Map(Seconds);  
    });

Однако вам придется делать это каждый раз.

Конечно, это не относится к «Я хотел бы сохранить этот класс как bigint…»

Вы хотите сказать, что хотите сохранить его как секунды?Если это так, вычистите все сверху и снова у вас есть два варианта:

  1. Реализация NHibernate IUserType (тьфу)
  2. Создание частного свойства или поля, в котором значение сохраняется в секундах.только и подключите только это до NHibernate.Получатели и установщики общедоступных свойств должны будут конвертировать в / из секунд.
0 голосов
/ 01 сентября 2010

Лично я еще не работал с AutoMappings, но я бы посоветовал заглянуть в IUserType NHibernate, чтобы изменить способ сохранения типа.Я полагаю, что это более чистый способ определения пользовательского сопоставления Time <-> bigint.

. При чтении приведенного выше кода Map(x => x.ToTimeSpan()) не будет работать, поскольку вы не можете встроить код преобразования приложения в базу данных в свои сопоставления.Даже если это было бы возможно, объявление пропускает преобразование из базы данных в приложение.A IUserType, с другой стороны, может выполнять пользовательские преобразования в методах NullSafeGet и NullSafeSet.

...