Как добавить подзапрос LINQ to XML в запрос LINQ to Entities? - PullRequest
1 голос
/ 13 июня 2019

У меня есть структура XML в столбце базы данных типа XML, которая выглядит примерно так:

<Translation>
   <Language ID="1">
       <Title>Some title</Title>
       <Abbrevation>some abbrevation</Abbrevation>
       <Source>https://www.somesource.com</Source>
   </Language>
   <Language ID="2">
       <Title>some more titles</Title>
       <Abbrevation>some more abbrevation</Abbrevation>
       <Source>https://www.somemoresource.com</Source>
          </Sprache>
</Translation>

Теперь мне нужно получить элементы этого XML в запросе LINQ to Entities. Что я пробовал до сих пор:

return from x in _context.Test
               where((displayAll == false && (x.Aufhebung == null || x.Aufhebung > DateTime.Now)) || (displayAll))
               select new TestViewModel()
               {
                   ID = x.ID,
                   Prop = x.Prop,
                   Number = x.Number ?? "",
                   Title = XElement.Parse(x.Translation).Descendants("Language").Where(f => f.FirstAttribute.Value == "1").Descendants("Title").Single().Value,
               };
    }

и свойство на модели:

public string Translation{ get; set; }

Но я всегда получаю сообщение об ошибке:

LINQ to Entities не распознает метод [System.Xml.Linq.XElement], System.Xml.Linq.XName, и этот метод нельзя преобразовать в выражение хранилища.

Есть ли способ получить подзапрос LINQ to XML в LINQ to Entities?

1 Ответ

1 голос
/ 13 июня 2019

Хотя «элемент базы данных» не материализован, каждое выражение в методах Linq будет переводиться как выражение SQL, когда это возможно ... но эта операция:

Title = XElement.Parse(x.Translation).Descendants("Language").Where(f => f.FirstAttribute.Value == "1").Descendants("Title").Single().Value

, как говорится в тексте сообщения об ошибке, не может быть переведено в выражение хранилища, это связано с наличием XElement и его методов.

Чтобы выполнить эту строку в методе Linq, вы должны материализовать IQueryable, возвращаемый

context.Test.where((displayAll == false && (x.Aufhebung == null || x.Aufhebung > DateTime.Now)) || (displayAll))

и затем продолжите выбор. В этом случае, чтобы материализовать этот IQueryable, в синтаксисе, не похожем на SQL, Linq предоставляет метод .ToList (), который в этом случае возвращает List , материализованный и готовый в памяти приложения для использования с каждым выражением приложения. .

...