Как использовать AliasJoin в QueryOver для этого примера

Класс Person имеет ассоциацию по классу Identity (один к одному), FirstName и LastName являются свойствами класса Person, а Sex и BirthDate являются свойствами класса Identity.

У меня есть запрос sql в качестве следующих примеров:

select FirstName,LastName,Identity.Sex,Identity.BirthDate from Person_Person as Person
inner join Person_Identity as Identity on Person.Id = Identity.Person_id_fk
WHERE FirstName like '%jack%' and LastName like '%smit%'

Я конвертирую его в QueyOver.

var q = SessionInstance.QueryOver<Person>();

if (!String.IsNullOrEmpty(searchPersonDto.FirstName)) //necessary
   q = q.Where(p => p.FirstName.IsLike(searchPersonDto.FirstName, MatchMode.Anywhere));

if (!String.IsNullOrEmpty(searchPersonDto.LastName))  //necessary
   q = q.Where(p => p.LastName.IsLike(searchPersonDto.LastName, MatchMode.Anywhere));

Person aliasPerson = null; 
q = q.SelectList(list => list
     .Select(p => p.Id).WithAlias(() => aliasPerson.Id)
     .Select(p => p.FirstName).WithAlias(() => aliasPerson.FirstName)
     .Select(p => p.LastName).WithAlias(() => aliasPerson.LastName)
     .Select(p => p.Identity.Sex).WithAlias(() => aliasPerson.Identity.Sex)
     .Select(p => p.Identity.BirthDate).WithAlias(() => aliasPerson.Identity.BirthDate))
   .TransformUsing(Transformers.AliasToBean<Person>());

q.List<Person>();

Но объединение в этом запросе неверно. Это сообщение вызывает исключение: could not resolve property: Identity.Sex of: Domain.Entities.Person

Как мне присоединиться к Identity by Person?

Обновлено: добавлен аналогичный запрос linq.

var q = SessionInstance.Query<Person>()
        .Where(p => p.FirstName == searchPersonDto.FirstName)
        .Select(p => new Person(p.Id)
        {            
            FirstName = p.FirstName,
            LastName = p.LastName,
            Identity = new Identity()
            {
                Sex = p.PersonIdentity.Sex,
                BirthDate = p.Identity.BirthDate
            }
        }).ToList<Person>();

Мне нужен запрос с помощью QueryOver, аналогичный приведенному выше запросу с помощью Linq.


person Ehsan    schedule 18.12.2011    source источник
comment
Глядя на ваш запрос, вам вообще не нужны никакие псевдонимы...   -  person Phill    schedule 18.12.2011
comment
@Phill Мне нужен псевдоним для q.List<Person>() вместо q.List<object>()   -  person Ehsan    schedule 18.12.2011
comment
нет, .List() уже возвращает вам тип IList‹Person›   -  person Phill    schedule 18.12.2011
comment
@Phill, этот запрос похож на SELECT * From Person_Person Но я этого не хочу. Я хочу этот запрос: SELECT FirstName,LastName, ... From Person_Person   -  person Ehsan    schedule 18.12.2011
comment
Ааа, теперь мы к чему-то пришли, вы хотите выбрать определенные столбцы, включая отношения.   -  person Phill    schedule 18.12.2011
comment
Я больше не буду тебе помогать, потому что у тебя дерьмовое отношение к тому, кто тебе помогает. Также вы можете уточнить, что вы просите в своем вопросе.   -  person Phill    schedule 18.12.2011
comment
@Phill Прости, почему ты так думаешь? Я с самого начала сказал, что мне нужен Select в QueryOver, аналогичный моему запросу Sql. А я сказал, что думаю проблема в JoinAlias. Не так ли? Еще раз извинения!   -  person Ehsan    schedule 22.12.2011


Ответы (1)


Update2: некрасиво, но вот

var results = q
    .JoinAlias(p => p.Identity, () => identityAlias)
    .SelectList(list => list
        .Select(p => p.Id)
        .Select(p => p.FirstName)
        .Select(p => p.LastName)
        .Select(p => identityAlias.Sex)
        .Select(p => identityAlias.BirthDate)
    .List<object[]>()
    .Select(values => new Person((int)values[0])
    {            
        FirstName = (string)values[1],
        LastName = (string)values[2],
        Identity = new Identity()
        {
            Sex = (string)values[3],
            BirthDate = (DateTime)values[4],
        }
    })
    .ToList<Person>();

Обновление: из ваших комментариев я бы сказал, что это то, что вам нужно.

код для заполнения PersonDto

PersonDTO aliasDTO = null;
q = q
    .JoinAlias(p => p.Identity, () => identityAlias)
    .SelectList(list => list
        .Select(p => p.Id).WithAlias(() => aliasDTO.Id)
        .Select(p => p.FirstName).WithAlias(() => aliasDTO.FirstName)
        .Select(p => p.LastName).WithAlias(() => aliasDTO.LastName)
        .Select(p => identityAlias.Sex).WithAlias(() => aliasDTO.Sex)
        .Select(p => identityAlias.BirthDate).WithAlias(() => aliasDTO.BirthDate))
    .TransformUsing(Transformers.AliasToBean<PersonDTO>())
    .List<PersonDTO>();

Оригинальный ответ:

q.JoinAlias(p => p.Identity, () => identityAlias)

// and later

.Select(p => identityAlias.Sex)

Обновление: в опубликованном коде AliasToBeanTransformer вообще не нужен

var q = SessionInstance.QueryOver<Person>();

if (!String.IsNullOrEmpty(searchPersonDto.FirstName)) //necessary
   q = q.Where(p => p.FirstName.IsLike(searchPersonDto.FirstName, MatchMode.Anywhere));

if (!String.IsNullOrEmpty(searchPersonDto.LastName))  //necessary
   q = q.Where(p => p.LastName.IsLike(searchPersonDto.LastName, MatchMode.Anywhere));

var results = q.Fetch(p => p.Identity).Eager
    .List<Person>();
person Firo    schedule 19.12.2011
comment
Я добавил ваш код. Ваше изменение попало в исключение из-за этого сообщения: Could not find a setter for property 'Sex' in class 'Domain.Entities.Person. Это исключение выдается в этой строке кода: q.Select(p => identityAlias.Sex).WithAlias(() => aliasPerson.PersonIdentity.Sex); - person Ehsan; 19.12.2011
comment
Проблема все еще существует. p.Identity.Sex и p.Identity.BirthDate имеют одинаковую ошибку времени выполнения: could not resolve property : .... Я хочу что-то подобное в высоком запросе Sql. - person Ehsan; 19.12.2011
comment
+1 Первый запрос в вашем ответе правильный Но мне это бесполезно. Мне нужен список Person (List<Person>) вместо списка PersonDTO (List<PersonDTO>) . - person Ehsan; 20.12.2011
comment
Второй запрос в вашем ответе имеет ошибку времени выполнения с помощью этого сообщения: Could not determine member from new PersonDTO() {FirstName = p.FirstName, LastName = p.LastName, ...}. Почему? - person Ehsan; 20.12.2011
comment
я удалил код для personDto, потому что он вам не нужен. Используйте запрос в обновленном ответе - person Firo; 20.12.2011
comment
Это энергичная загрузка, а не ленивая загрузка. Я хочу выбрать определенные столбцы, включая отношения. Это как-то с ленивой загрузкой и выбором определенных столбцов? - person Ehsan; 20.12.2011
comment
Я не уверен, чего ты хочешь. Вам нужны объекты Person или только некоторые свойства объекта Person+Identity? - person Firo; 20.12.2011
comment
Я хочу выбрать определенные столбцы Person и Identity в виде списка Person, другие свойства которого в объекте Person и объекте Identity равны нулю. Моя проблема точно такая же. - person Ehsan; 20.12.2011
comment
это нарушило бы контракт объекта, потому что неизвестно, имеет ли Peron нулевые свойства или неинициализированные свойства, и ленивая загрузка и сохранение изменений будут нарушены. Я настоятельно рекомендую вам создать файл personDto, в котором будет инкапсулирована только нужная вам информация. - person Firo; 20.12.2011
comment
По причинам, по которым мне просто нужен объект Person. Я решаю эту проблему с помощью linq. Мой запрос linq добавлен к вопросу. Мне нужно Select в QueryOver, аналогичное Select в запросе linq. - person Ehsan; 21.12.2011
comment
Я тоже не знаком с QueryOver. Я всегда использовал linq. Но я бы хотел. QueryOver нужно изучить, и теперь мне нужно, как использовать Select в QueryOver. Таким образом, QueryOver не поддерживает Select? - person Ehsan; 22.12.2011