Entity Framework Query Xml - PullRequest
       6

Entity Framework Query Xml

7 голосов
/ 09 июля 2009

Как бы вы создали этот запрос с 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(...)

Ответы [ 2 ]

10 голосов
/ 09 июля 2009

Ни один из языков запросов 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;

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

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

Alex

Руководитель программы Entity Framework Team

2 голосов
/ 09 июля 2009

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

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

LINQ to Entities не знает о возможностях XML сервера БД.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...