Где NHibernate с типом пользователя

У меня много проблем с тем, чтобы заставить nHibernate сделать предложение where in для поля, которое сопоставлено с реализацией IUserType. Все типы ниже упрощены для вопроса.

У меня есть таблица, которая выглядит примерно так:

int id
nvarchar notPartOfUserType
nvarchar partOfUserType1
nvarchar partOfUserType2
nvarchar partOfUserType3
...

это сопоставлено с объектом

int Id
string NotUserType
UserType UserType
...

и UserType выглядит примерно так

string Part1
string Part2
string Part3
...

partOfUserType1, partOfUserType2 и partOfUserType3 сопоставляются для выхода из базы данных в UserType путем реализации IUserType в UserTypeMapping. Вот NullSafeGet для этого класса. Это не так сложно.

        public object NullSafeGet(IDataReader rs, string[] names, object owner)
    {
        var field1 = NHibernateUtil.String.NullSafeGet(rs, names[0]) as string;
        var field2 = NHibernateUtil.String.NullSafeGet(rs, names[1]) as string;
        var field3 = NHibernateUtil.String.NullSafeGet(rs, names[2]) as string;

        return new UserType
        {
            Part1 = field1
            Part2 = field2,
            Part3 = field3
        };
    }

И это отображается кодом. Вот выдержка из этого свойства

        Property(p => p.UserType, map =>
        {
            map.Columns(m => m.Part1("partOfUserType1"), m => m.Part2("partOfUserType2"), m => m.Part3("partOfUserType3"));
            map.Type<UserTypeMapping>();
        });

Все мои обычные загрузки и сохранения/обновления работают нормально. Я также могу сделать предложение Where In для полей, не являющихся частью UserType, просто отлично:

var list = new List<string> {"123", "456"};
var result = session.Query<MyType>().Where(row => list.Contains(row.NotUserType)).ToList();

Но проблема: я хочу сделать предложение where in в поле partOfUserType1. Я не могу на всю жизнь заставить это работать. Я пробовал все возможные способы использования провайдера Linq и синтаксиса QueryOver. Нет игральных костей.

Это возможно?

РЕДАКТИРОВАТЬ - РЕШЕНИЕ

Спасибо Оскару Берггрену за то, что он привел меня к этому ответу. В этом случае мне следовало использовать карту компонентов, а не тип пользователя.

До

Property(p => p.UserType, map =>
{
    map.Columns(m => m.Part1("partOfUserType1"), m => m.Part2("partOfUserType2"), m => m.Part3("partOfUserType3"));
    map.Type<UserTypeMapping>();
});

После

Component(c => c.UserType, component =>
{
    component.Property(p => p.Part1, map => map.Column("partOfUserType1"));
    component.Property(p => p.Part2, map => map.Column("partOfUserType2"));
    component.Property(p => p.Part3, map => map.Column("partOfUserType3"));
});   

Конечно, мой фактический тип намного сложнее, требуя пользовательского типа в сопоставлении компонентов. Но сейчас это хорошо работает.


person CPMike    schedule 18.04.2016    source источник
comment
Вы пробовали list.Contains(row.NotUserType.Part1)?   -  person Stefan Steinegger    schedule 19.04.2016
comment
Извините, переименовывая все в более общем виде для вопроса, я, должно быть, избавился от свойства в этом утверждении. Да, я пробовал 'list.Contains(row.UserType.Part1)'. nHibernate выдает из глубины «не удалось разрешить свойство: Part1 of: MyType». Что странно, так как Part1 является свойством MyType, но MyType.UserType. Я начинаю думать, что nHibernate вообще не может использовать предложение Where In с IUserType.   -  person CPMike    schedule 19.04.2016


Ответы (1)


Если вы хотите запросить части пользовательского типа, я думаю, вам следует рассмотреть использование сопоставления компонентов вместо пользовательского типа.

person Oskar Berggren    schedule 23.04.2016
comment
Большое спасибо! Я не знал о сопоставлении компонентов. Красиво работал. Теперь мне просто нужно повторно реализовать весь явный sql, который я сделал, чтобы обойти проблему. Я обновил вопрос с решением. - person CPMike; 25.04.2016