Вопрос

Как бы вы построили этот запрос с помощью Entity Framework:

SELECT  *
FROM    TreeNodes
WHERE   data.value('(/edumatic/assessmentItem/@type)[1]', 'nvarchar(max)') like 'multiplechoice1'

столбец данных — XML.По-видимому, это преобразуется в строку с помощью Entity Framework...

Это мое начало, но отсюда я не знаю, как добавить где...

var query = from e in edumatic3Context.TreeNodes
                        where e.Data.???????
                        select e;

            foreach (var treeNode in query)
                Console.WriteLine("{0} {1} {2} {3}", treeNode.TreeNodeId, treeNode.Name, treeNode.Type, treeNode.DateChanged);

Я также попробовал что-то вроде следующего кода, но это тоже не сработало:

var sql = "SELECT VALUE treeNode FROM TreeNodes as treeNode WHERE data.value('(/edumatic/assessmentItem/@type)[1]', 'nvarchar(max)') like 'multiplechoice1'";
            var query = edumatic3Context.CreateQuery<TreeNodes>(sql);

foreach(...)
Это было полезно?

Решение

Ни один из языков запросов Entity Framework (LINQ to Entities и eSQL) напрямую не поддерживает вложенные XML-запросы.Так что вы не сможете сделать такого рода вещи.Если вы не запустите XML-запрос после вызова AsEnumerable(), что, конечно, несколько нежелательно с точки зрения производительности.

Однако вы, вероятно, можете написать функцию сохранения в SSDL, которая сделает этот фильтр за вас.

Откройте файл EDMX в редакторе XML и попробуйте добавить элемент в раздел StorageModel (т.SSDL).А <CommandText> (Я думаю, именно так она и называется) этой функции хранилища — это место, где вы можете написать соответствующий T-SQL, а также ссылаться на параметры функции.Извините, у меня нет такого удобного примера.

Сделав это, вы можете вызвать функцию Store в eSQL, т.е.что-то вроде этого:

SELECT VALUE treeNode FROM TreeNodes as treeNode WHERE 
StorageModelNamespace.MyXmlWrapperFunctionForNVarchar('(/edumatic/assessmentItem/@type)[1]', treeNode.Data) LIKE 'multiplechoice1'

В .NET 4.0 вы также сможете написать функцию-заглушку в .NET, чтобы вы могли вызывать эту функцию и в LINQ:

то есть

[EdmFunction("StorageModelNamespace", "MyXmlWrapperFunctionForNVarchar"]
public static string MyXmlHelper(string path, string data)
{
   throw new NotImplementedException("You can only call this function in a LINQ query");
}

тогда что-то вроде этого:

var query = from e in edumatic3Context.TreeNodes
            where MyXmlHelper("(/edumatic/assessmentItem/@type)[1]", e.Data)
                 .StartsWith("multiplechoice1")
            select e;

Обратите внимание, что весь приведенный выше код — это всего лишь псевдокод. На самом деле я его не проверял, я просто пытаюсь помочь вам начать работу.

Надеюсь это поможет

Алекс

Менеджер программы Entity Framework Team

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

Два варианта:

  1. Напишите процедуру, которая возвращает все данные, необходимые для сопоставления с типом сущности, и поместите туда свой SQL.Этот метод может использовать индекс XML на сервере БД.
  2. Получите данные на клиенте, затем создайте XML-документ и используйте LINQ to XML.Удобен для программиста, но не может использовать XML-индекс.

LINQ to Entities не знает о функциях XML сервера БД.

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