Вопрос

У меня есть модель поверх моей модели базы данных и я сопоставляю объекты в моем репозитории.

Однако, по-видимому, имеет значение, "выбираю ли я new" непосредственно в моих getUsers или "выбираю factoryresult", как реализовано ниже.Во время выполнения я получаю сообщение об ошибке, что метод CreateFromDbModel не имеет перевода в sql (System.Исключение NotSupportedException).

Есть ли способ обойти это?Могу ли я как-нибудь это исправить?

Причина, по которой я хочу использовать фабричный метод, заключается в том, что я могу создавать экземпляры объектов в другом месте и хочу сохранить "код сопоставления" в одном месте...

Спасибо за любые комментарии, Андерс

    public IQueryable<User> GetUsers(bool includeTeams)
    {
        return from u in _db.sc_Players
               where (includeTeams || (!u.aspnet_User.sc_Player.IsTeam))
               select UserFactory2.CreateFromDbModel(u);
    }


    public static User CreateFromDbModel(sc_Player player)
    {
        return new User
                   {
                       Id = player.sc_PlayerID,
                       FirstName = player.FirstName.Trim(),
                       LastName = player.LastName.Trim(),
                       PresentationName = player.FirstName.Trim() + " " + player.LastName.Trim(),
                       LoginName = player.aspnet_User.LoweredUserName,
                       IsTeam = player.IsTeam,
                       Email = player.aspnet_User.aspnet_Membership.Email,
                       Password = player.aspnet_User.aspnet_Membership.Password
                   };
    }
Это было полезно?

Решение

Проблема в том, что вы возвращаете IQueryable в своем методе getUsers?Вместо этого попробуйте вернуть List.Это заставит запрос Linq выполняться внутри метода.

public List<User> GetUsers(bool includeTeams)
{
    return (from u in _db.sc_Players
    where (includeTeams || (!u.aspnet_User.sc_Player.IsTeam))
    select UserFactory2.CreateFromDbModel(u)).ToList();
}

Не уверен, решит ли это проблему, просто догадка.Я смог продублировать то, что вы делаете в Linqpad, в локальной базе данных, и это сработало.Но мой образец не возвращал IQueryable .Продолжаете ли вы изменять коллекцию IQueryable за пределами getUsers()?

Редактировать:

Я провел еще кое-какую проверку.Я смог воспроизвести ошибку только тогда, когда я изменил свой образец, чтобы коллекция IQueryable использовалась во втором запросе Linq после вызова getUsers():

IQueryable<User> query = GetUsers(true);

var q = from u in query
    where u.Name.Contains("Bob")
    select new {Name = u.FirstName + " " + u.LastName};

Бьюсь об заклад, если вы вернете список, как предложено выше, в getUsers(), ошибка исчезнет.Единственным недостатком является то, что любая фильтрация, которую вы выполняете после вызова getUsers(), не будет ограничивать объем данных, возвращаемых из базы данных, потому что вы уже выполнили запрос при вызове .ToList().

Правка 2:

К сожалению, я не думаю, что есть какой-либо другой способ включить ваш фабричный метод в запрос.У меня есть еще одна идея.Вы можете создать метод расширения для IQueryable, назовите его чем-то вроде ToUserList().Внутри ToUserList() вы вызываете ToList() по запросу и вашему заводскому методу, который возвращает коллекцию пользователей.Вызовите этот метод, когда вы закончите фильтрацию данных с помощью Linq.Это позволит вам выполнить запрос только тогда, когда вы будете готовы загрузить данные из базы данных.Пример приведен ниже.

public static List<Users> ToUserList(this IQueryable<User> query)
{
     return query.ToList().Select(u => UserFactory2.CreateFromDbModel(u)); 
}

Вызовите метод расширения следующим образом:

// Filter the data using linq. When you are ready to execute the query call:
query.ToUserList(); // Query will execute and a list of User objects returned.

Надеюсь, в этом есть смысл.Дуглас Х.

Другие советы

Ошибка в значительной степени объясняет все это.

"метод CreateFromDbModel не имеет перевода в sql (System.Исключение NotSupportedException)"

Ваш метод CreateFromDbModel не является функцией sql.Ваше приложение не сможет запустить функцию CreateFromDbModel до тех пор, пока объекты не будут специально возвращены вам с сервера.Скорее всего, вам придется вызвать ToList() или что-то подобное в вашем запросе, прежде чем вы сможете запустить CreateFromDbModel для них.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top