Как использовать классы фабрики с linq для sql?

Если объем вложения, в котором Вы нуждаетесь, фиксируется, collections.defaultdict замечательно.

, например, вложение два глубоко:

myhash = collections.defaultdict(dict)
myhash[1][2] = 3
myhash[1][3] = 13
myhash[2][4] = 9

, Если Вы хотите пойти другой уровень вложения, необходимо будет сделать что-то как:

myhash = collections.defaultdict(lambda : collections.defaultdict(dict))
myhash[1][2][3] = 4
myhash[1][3][3] = 5
myhash[1][2]['test'] = 6

редактирование: MizardX указывает, что мы можем получить полную степень универсальности с простой функцией:

import collections
def makehash():
    return collections.defaultdict(makehash)

Теперь мы можем сделать:

myhash = makehash()
myhash[1][2] = 4
myhash[1][3] = 8
myhash[2][5][8] = 17
# etc
6
задан Anders Juul 2 September 2009 в 08:02
поделиться

2 ответа

Проблема в том, что вы возвращаете 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 ()?

Edit:

Я проверил еще раз. Мне удалось продублировать ошибку только тогда, когда я изменил свой образец, поэтому коллекция 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.

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

1
ответ дан 17 December 2019 в 20:33
поделиться

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

«метод CreateFromDbModel не имеет перевода в sql (System.NotSupportedException)»

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

1
ответ дан 17 December 2019 в 20:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: