#entity-framework-4 #linq-to-entities #sql-server-ce-4
#entity-framework-4 #linq-to-entities #sql-server-ce-4
Вопрос:
У меня есть этот запрос LINQ:
var children = DataContext.Entities.Nodes
.Where(n => n.Parent.Name == node.Key)
.OrderBy(n => n.SortOrder);
foreach (var child in children)
var childNode = CreateNode(child);
При использовании SQL Server все работает нормально. Однако при использовании SqlCe я получаю следующую ошибку:
[SqlCeException (0x80004005): Not implemented]
System.Data.SqlServerCe.SqlCeDataReader.ProcessResults(Int32 hr) 125
System.Data.SqlServerCe.SqlCeDataReader.IsEndOfRowset(Int32 hr) 131
System.Data.SqlServerCe.SqlCeDataReader.Move(DIRECTION direction) 376
System.Data.SqlServerCe.SqlCeDataReader.Read() 95
System.Data.Common.Internal.Materialization.Shaper`1.StoreRead() 44
[EntityCommandExecutionException: An error occurred while reading from the store provider's data reader. See the inner exception for details.]
System.Data.Common.Internal.Materialization.Shaper`1.StoreRead() 130
System.Data.Common.Internal.Materialization.SimpleEnumerator.MoveNext() 46
Есть идеи, что здесь происходит?
Я даже ToArray()
раньше foreach
пытался вызывать, но это не помогло.
Редактировать:
Если я изменю запрос на:
var children = DataContext.Entities.Nodes
.Where(n => n.Parent.Name == node.Key)
.ToArray()
.OrderBy(n => n.SortOrder);
Это работает… почему?
ПРАВКА 2: КСТАТИ, Parent
навигатор указывает на одну и ту же таблицу, поэтому у каждой Node
может быть родительский элемент {0..1} Node
.
Комментарии:
1. Я получал аналогичную ошибку в своем EF-коде, но я полагаю, что это было исключение взаимоблокировки транзакции. Интересно, не заставляет ли toArray перед OrderBy выполнять больше обработки в вашем коде C #, а не в БД, сокращая время обработки в БД и, таким образом, уменьшая вероятность возникновения взаимоблокировки в БД?
2. @deverop Вы нашли решение для этого или перешли к Microsoft? Я вижу нечто подобное без Entity Framework, но это сложнее воспроизвести. У вас есть полный пример?
3. @Travis Нет, я не нашел решения и не наращивал. В итоге я изменил запрос и разбил его, вызвав
ToArray()
перед сортировкой.4. @адаптивный облом. Является ли сценарий дублирования таким же простым, как наличие таблицы с родительской связью и выполнение запроса where / orderby выше? Или ваше отображение было более сложным, чем это?
5. @Travis Таблица должна иметь циклическую ссылку на саму себя. В моем случае узел может иметь родительский, а также дочерний тип
Node
.
Ответ №1:
Тот факт, что запрос в вашем разделе редактирования работает, указывает на то, что проблема заключается в OrderBy(n => n.SortOrder)
предложении, потому что только эта часть запроса …
DataContext.Entities.Nodes
.Where(n => n.Parent.Name == node.Key)
… фактически выполняется на сервере. Вызывая .ToArray()
, вы принудительно выполняете запрос и в память загружается (несортированный) список. Следующее OrderBy
определяет запрос в этом списке (который является IEnumerable
и больше не является IQueryable
an). Затем этот второй запрос будет выполнен в памяти в этом списке, и EF или SqlCe не участвуют в этой сортировке.
Но в целом SqlCe поддерживается OrderBy
, поэтому остается вопрос, почему первый запрос выдает исключение.
По какому типу Node.SortOrder
вы пытаетесь выполнить сортировку? Является ли оно, например, обнуляемым или каким-то «экзотическим» типом, по которому SqlCe не может сортировать?
Комментарии:
1.
Node.SortOrder
являетсяint
. Могу ли я также добавить, что переключениеOrderBy
иWhere
не имеет значения. Итак,DataContext.Entites.Nodes.OrderBy(n => n.SortOrder).Where(n => n.Parent.Name == node.Key)
выдает то же самое исключение.2. @deverop: Вы также проверяли, выдает ли он исключение, если вы только сортируете (
OrderBy
безWhere
) или если вы только фильтруете (Where
безOrderBy
)? Это также было бы интересно, чтобы сузить проблему.3. Спасибо за предложение.
OrderBy
само по себе работает, и то же самое относится кWhere
(как показано в вопросе). Но я просто не могу использовать их вместе.4. @deverop: Боюсь, что у меня больше нет идеи. Выполняемый вами запрос выглядит довольно простым, и я не понимаю, почему он может завершиться ошибкой. Я бы рекомендовал задать этот вопрос также непосредственно в Microsoft, чтобы повысить ваши шансы на решение — например, здесь: social.msdn.microsoft.com/forums/en-US/adodotnetentityframework /…