ССЫЛКА на объект:использование Contains в части “выбрать” приводит к непредвиденной ошибке
-
03-07-2019 - |
Вопрос
У меня есть запрос LINQ, направленный против объекта Entity Framework.Вот краткое изложение запроса:
//a list of my allies
List<int> allianceMembers = new List<int>() { 1,5,10 };
//query for fleets in my area, including any allies (and mark them as such)
var fleets = from af in FleetSource
select new Fleet
{
fleetID = af.fleetID,
fleetName = af.fleetName,
isAllied = (allianceMembers.Contains(af.userID) ? true : false)
};
По сути, то, что я делаю, - это собираю набор флотов.Список allianceMembers содержит целые числа всех пользователей, которые состоят в союзе со мной.Я хочу установить isAllied = true, если владелец автопарка является частью этого списка, и false в противном случае.
Когда я делаю это, я вижу исключение:"LINQ to Entities не распознает метод 'Boolean Содержит метод (Int32)'"
Я могу понять получение этой ошибки, если бы я использовал contains в части where запроса, но почему я должен получать ее в select?К этому моменту я бы предположил, что запрос был бы выполнен и вернул результаты.Этот небольшой фрагмент кода вообще никак не ограничивает мои данные.
Есть какие-нибудь советы о том, как еще я могу выполнить то, что мне нужно, установив флаг isAllied?
Спасибо
Решение
var fleets = from af in FleetSource;
var x = from u in fleets.ToList()
select new Fleet
{
fleetID = u.fleetID,
fleetName = u.fleetName,
isAllied = (allianceMembers.Contains(u.userID) ? true : false)
}
зовущий ToList()
на флотах запрос выполняется, позже вы можете использовать Contains()
.
Другие советы
Это взято из предыдущего ответа...
Содержит не поддерживаемые файлы.
IN и JOIN - это не один и тот же оператор (фильтрация по IN никогда не изменяет количество элементов запроса).
Вместо того, чтобы делать это таким образом, используйте метод join .Это несколько сложно понять без использования операторов запроса, но как только вы это получите, у вас все получится.
var foo =
model.entitySet.Join( //Start the join
values, //Join to the list of strings
e => e.Name, // on entity.Name
value => value, //equal to the string
(ModelItem ent, String str) => ent);//select the entity
Здесь он использует операторы запроса
var foo = from e in model.entitySet
join val in values on
e.Name equals val
select e;
По сути, entity Framework пытается перевести ваш запрос LINQ в инструкцию SQL, но не знает, как обработать Contains
.
Что вы можете сделать вместо этого, так это извлечь свои автопарки из базы данных и позже установить свойство isAllied:
var fleets = (from af in FleetSource
select new Fleet
{
fleetID = af.fleetID,
fleetName = af.fleetName,
userId = af.userId
}).AsEnumerable();
foreach (var fleet in fleets)
{
fleet.isAllied = (allianceMembers.Contains(fleet.userID) ? true : false);
}
Все, кто выше меня, ошибаются!!!(Без обид ...) Это не работает, потому что вы используете перегрузку IList "Contains", а не перегрузку IEnumerable "Contains".Просто измените на:
allianceMembers.Contains<int>(af.userID)
Путем добавления <int>
, вы указываете компилятору использовать перегрузку IEnumerable вместо перегрузки IList.