C# LINQ, где аргументы типа предиката
-
22-08-2019 - |
Вопрос
У меня есть XElement со значениями для фиктивных данных.
У меня есть выражение для запроса XML:
Expression<Func<XElement, bool>> simpleXmlFunction =
b => int.Parse(b.Element("FooId").Value) == 12;
используется в:
var simpleXml = xml.Elements("Foo").Where(simpleXmlFunction).First();
Ошибка времени проектирования:
Аргументы типа для метода System.Linq.Enumerable.Where(System.Collections.Generic.IEnumerable, System.Func) не могут быть выведены из использования.Попробуйте явно указать аргументы типа.
Делегат, предоставленный в Where, должен принять XElement и вернуть логическое значение, отмечая, соответствует ли элемент запросу. Я не уверен, как добавить что-либо еще к делегату или предложениюwhere, чтобы отметить тип.
Кроме того, параллельный метод для реальной функции в Entity Framework не имеет этой проблемы.Что не так с версией LINQ-to-XML?
Решение
Не делайте simpleXmlFunction выражением Expression<Func<XElement, bool>>.Сделайте это Func<XElement, bool>.Это то, что ожидается от делегата .Where.
Func<XElement, bool> simpleXmlFunction =
new Func<XElement, bool>(b => int.Parse(b.Element("FooId").Value) == 12);
Другие советы
Я думаю, что полный ответ включает в себя предыдущий ответ, комментарий Дэвида Мортона и обновленный фрагмент кода:
Реализация .Where для IQueryable отличается от реализации .Where для IEnumerable.IEnumerable.Where ожидает:
Func<XElement, bool> predicate
Вы можете скомпилировать функцию из имеющегося у вас выражения, выполнив:
Expression<Func<XElement, bool>> simpleXmlExpression =
b => int.Parse(b.Element("FooId").Value) == 12;
Func<XElement, bool> simpleXmlFunction = simpleXmlExpression.Compile();
var simpleXml = xml.Elements("Foo").Where(simpleXmlFunction).First();
Это позволит вам просмотреть сгенерированное дерево выражений и использовать скомпилированную форму для запроса коллекции xml.