Вопрос

У меня есть запрос Linq to Entities, подобный этому:

var results = from r in entities.MachineRevision
              where r.Machine.IdMachine == pIdMachine
                 && r.Category == (int)pCategory
              select r;

Обычно я использую приведенный ниже код, чтобы проверить, возвращаются ли некоторые результаты:

if (results.Count() > 0)
{
    return new oMachineRevision(results.First().IdMachineRevision);
}

Однако я получаю Неподдерживаемое исключение в если состояние.

Сообщение об ошибке: Невозможно создать постоянное значение типа «Тип закрытия».В этом контексте поддерживаются только примитивные типы (такие как Int32, String и Guid).

Обратите внимание, что pКатегория является типом Enum.

Это было полезно?

Решение

РЕДАКТИРОВАТЬ:Судя по вашему обновлению, ошибка может быть связана с перечислением в вашем классе сущности.Видеть это запись в блоге для получения дополнительной информации и обходного пути.Я оставляю свой первоначальный ответ как улучшение синтаксиса вашего запроса.

Попробуйте выбрать первую сущность в самом запросе с помощью FirstOrDefault, а затем проверьте, является ли результат нулевым.

int compareCategory = (int)pCategory; // just a guess
var result = (from r in entities.MachineRevision
              where r.Machine.IdMachine == pIdMachine
                 && r.Category == compareCategory
              select r).FirstOrDefault();

if (result != null)
{
     return new oMachineRevision(result.IdMachineRevision);
}

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

Почему бы просто не использовать FirstOrDefault() и проверить значение null?Я не вижу преимущества в запросе счетчика и последующем получении первого элемента.

В стандартной реализации linq операторы «select» и «where» соответствуют методам, возвращающим IEnumerable или IQueryable.Таким образом, стандартные методы linq при использовании всегда должны возвращать IEnumerable из вашего запроса, а не один объект.

Но методы linq, являющиеся кандидатами на роль операторов linq, не ограничиваются методами, возвращающими IEnumerables, можно выбрать любой метод, возвращающий что угодно.

Если у вас есть методы экземпляра с именами «Выбрать» и «Где», которые возвращают один объект, или методы расширения, специфичные для вашего класса и возвращающие один объект, они будут использоваться вместо стандартных методов linq.

Я предполагаю, что метод «Выбрать» или «Где», определенный в вашем классе, заставляет linq возвращать одно значение вместо IEnumerable<T>.

Я не знал, что в зависимости от результата запроса будут создаваться разные анонимные объекты.Я думаю, они просто хотели, чтобы результаты имели тип IEnumerable.

Как насчет использования foreach?

var results = from r in entities.MachineRevision
              where r.Machine.IdMachine == pIdMachine
                 && r.Category == pCategory
              select r;

foreach( var r in results )
{
    yield return new oMachineRevision( r.IdMachineRevision );
}

Это касается и всех неявных типов.Должен признаться, я все время об этом забывал, и именно поэтому наткнулся на этот пост.

если у вас есть

class ClassA {
               ...

               private string value;

               ...

               public static implicit operator string(ClassA value)
               {
                    return value.ToString();
               } 

              ...
}

вам нужно явно привести класс к строке для сравнения.

поэтому я обычно делаю это

    var myClassAStr = myClassA.ToString();

    var x = (from a in entites where a.ValToCompare == myClassAStr select a).first();

// do stuff with x
    ...

попробуйте использовать

IENumerable<MachineRevision> results = from r in entities.MachineRevision
...

вместо.

Я думаю, что ваша проблема вызвана var.

Редактировать:

Прочтите сообщение об ошибке.«Невозможно создать постоянное значение типа «Тип закрытия».В этом контексте поддерживаются только примитивные типы («такие как Int32, String и Guid»).

Одно из этих сравнений связано с типом, отличным от int, string или guid.Я предполагаю, что Категория.

r.Machine.IdMachine == pIdMachine && r.Category == pCategory

Интересно, что LinqToSql допускает такую ​​конструкцию.Не знаю, почему LinqToEntities не поддерживает это.

Я думаю, вы также можете выбрать нужный элемент другим, более простым способом, используя лямбда-выражения.

var result = entities.MachineRevision
                 .Where(x => x.Machine.IdMachine == pIdMachine)
                 .Where(y => y.Category == (int)pCategory)
                 .FirstOrDefault();

if (result != null)
{
     return new oMachineRevision(result.IdMachineRevision);
}

а затем действуйте, как обычно

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