Linq nested select new не работает - PullRequest
       9

Linq nested select new не работает

2 голосов
/ 10 августа 2009

Я пытаюсь получить готовую загрузку, работая с Subsonic, и он возвращает мне ноль.

В приведенном ниже методе я пытаюсь гидрировать модель домена (UserModel), которая содержит другую модель домена (CompanyModel). Однако с помощью приведенного ниже кода UserModel.Company всегда имеет значение null.

Что мне здесь не хватает. Любая помощь будет оценена.

public IList<UserModel> GetUsers()
{             
    return (from u in SubsonicSqlServer.Users.All()
            select new UserModel
                       {
                           UserId= u.UserId,
                           Company = (from c in u.Companies
                                    select new CompanyModel
                                               {
                                                   CompanyId = c.CompanyId,
                                                   CompanyName = c.CompanyName
                                               }).SingleOrDefault(),
                           FirstName = u.FirstName,
                           LastName = u.LastName,
                           BirthDate = u.BirthDate
                       }).ToList();

}

Обновление (08/11/09):

Более подробно изучая код, я обнаружил, что настройка CompanyId в следующем примере также не работает. Сначала я думал, что это проблема с Subsonic, но если приведенный ниже код не работает, я предполагаю, что это как-то связано с моим утверждением Linq. Есть идеи?

public IList<UserModel> GetUsers()
{             
    return (from u in SubsonicSqlServer.Users.All()
            select new UserModel
                       {
                           UserId= u.UserId,                            
                           CompanyId = Guid.NewGuid(),
                           FirstName = u.FirstName,
                           LastName = u.LastName,
                           BirthDate = u.BirthDate
                       }).ToList();

}

Обновление (17.11.2009):

Все еще не нашли решение. Но мы переключаемся на nHibernate (не из-за этой проблемы).

Ответы [ 3 ]

2 голосов
/ 18 августа 2009

"UserModel.Company всегда имеет значение null."

, поскольку вы устанавливаете это с помощью выражения, которое заканчивается на .SingleOrDefault(), я собираюсь предположить, что запрос не возвращает ни одного элемента. Начни там расследование. Если вы ожидаете ровно один элемент в u.Companies, измените значение на .Single() и вызовите ранний сбой.

Вы можете сделать .Single() перед созданием нового объекта CompanyModel, я думаю.

Что касается стиля, мне нравится синтаксис понимания запросов ("from x in y select"), но я нахожу его неудобным в сочетании с традиционным синтаксисом точечных обозначений. Это просто трудно читать. ( LINQ - Свободное выражение и выражение запроса - есть ли одно или несколько преимуществ одного над другим? ).

Подумайте об использовании let в понимании запроса, чтобы сделать его более понятным.

Кроме того, поскольку запрос уже возвращает IEnumerable<T>, а вызов ToList() заставляет все элементы быть реализованными, я бы изменил свой метод, чтобы вернуть IEnumerable<T>, если это возможно.

Итак, в вашем случае, я бы сделал рефакторинг первым, чтобы сказать:

public IEnumerable<User> GetUsers()
{ 
    return from u in SubsonicSqlServer.Users.All()
        let c = u.Companies.Single()
        select new UserModel
        {
            UserId = u.UserId,
            Company = new CompanyModel
            {
                CompanyId = c.CompanyId,
                CompanyName = c.CompanyName
            },
            FirstName = e.FirstName,
            LastName = e.LastName,
            BirthDate = e.BirthDate
        };
}

Если это имеет смысл в вашей объектной модели, вы можете изменить User, чтобы иметь конструктор, который принимает любой тип u, и это становится еще проще:

return from u in SubsonicSqlServer.Users.All()
    select new UserModel (u);

или даже

return SubsonicSqlServer.Users.All().Select(u => new UserModel (u));
0 голосов
/ 20 августа 2009

Пожалуйста, проверьте мой fork @ github (http://github.com/funky81/SubSonic-3.0/commit/aa7a9c1b564b2667db7fbd41e09ab72f5d58dcdb) для этого решения, на самом деле есть проблема, когда дозвуковая попытка спроектировать новый класс типов, так что на самом деле в вашем коде нет ничего плохого: D

0 голосов
/ 18 августа 2009

Две вещи

  1. Вы возвращаете List<UserModel>, когда в строке подписи вашего метода написано, IList<User> наследует UserModel от User?

  2. Я что-то упустил, откуда взялась e? 1014 *

FirstName = e.FirstName, LastName = e.LastName, Дата рождения = e.BirthDate Blockquote

...