В этом контексте поддерживаются только примитивные типы или типы перечисления

c# asp.net-mvc linq entity-framework

65457 просмотра

3 ответа

Я видел много вопросов на эту тему, но я не смог разобрать ни один из них, который действительно решит проблему, которую я вижу. У меня есть объект действия, который отслеживает, какому сотруднику он назначен, а также какому сотруднику была создана запись и обновлена ​​ее. Если я удалю строку кода `where a.AssignedEmployee == currentUser ', я не получу ошибку времени выполнения ниже.

Невозможно создать постоянное значение типа «DataModels.Employee». В этом контексте поддерживаются только примитивные типы или типы перечисления.

КОНТРОЛЛЕР

var query = from a in db.Activities
            where a.AssignedEmployee == currentUser
            where a.IsComplete == false
            orderby a.DueDate
            select a;
return View(query.ToList());

ПОСМОТРЕТЬ

@model IEnumerable<Data.DataModels.Activity>
..........
Автор: RSolberg Источник Размещён: 12.11.2019 09:11

Ответы (3)


64 плюса

Решение

Я предполагаю, что ошибка означает, что EF не может преобразовать оператор равенства для Employeeв SQL (независимо от того, предполагаете ли вы ссылочное равенство или переопределенный ==оператор). Предполагая, что Employeeкласс имеет уникальный идентификатор try:

var query = from a in db.Activities
            where a.AssignedEmployeeId == currentUser.Id
            where a.IsComplete == false
            orderby a.DueDate
            select a;
return View(query.ToList());
Автор: D Stanley Размещён: 04.03.2013 09:24

8 плюса

Не нравится тот факт, что вы пытаетесь преобразовать все объектное равенство в запрос к базе данных. Вы можете выполнять запросы структуры сущностей только с использованием константных значений, так же как и запросы SQL. Чтобы решить эту проблему, можно сравнить идентификаторы, чтобы увидеть, совпадает ли идентификатор AssignedEmployee с идентификатором текущего пользователя в таблице сотрудников.

В качестве примечания: если currentUserотслеживаемый объект не относится к типу Employee, вы можете рассмотреть возможность кэширования соответствующей записи Employee этого пользователя, чтобы иметь возможность ссылаться на нее в последующих запросах. Это было бы намного лучше, чем пытаться постоянно проходить через этот стол. (Опять же, это повлияет на вас, только если оно находится в другой таблице)

Автор: IronMan84 Размещён: 04.03.2013 09:24

5 плюса

Проблема с использованием == и obj.Equals заключается в том, что Entity Framework не знает, как перевести этот вызов метода в SQL - даже если вы перегрузите эти два метода во что-то, что будет преобразовано в SQL. Чтобы исправить этот недостаток в Entity Framework, вы можете создать метод, который возвращает дерево выражений, которое выполняет более сложную проверку на равенство, которую вы хотите выполнить.

Например, допустим, у нас есть следующий класс

public class Person {
    public string Firstname { get; set; } 
    public string Lastname  { get; set; }
}

Чтобы вернуть пользовательскую операцию равенства, понятную Entity Framework, добавьте следующий метод в класс Person:

public static Expression<Func<Person, bool>> EqualsExpressionTree(  Person rhs )
{
    return ( lhs ) => string.Equals( lhs.Firstname, rhs.Firstname ) &&
                      string.Equals( lhs.Lastname, rhs.Lastname );
}

В ваших запросах LINQ вы можете использовать свой собственный код равенства следующим образом:

Person anotherPerson = new Person { Firstname = "John", Lastname = "Doe" }
personCont.Where( Person.EqualsExpressionTree(anotherPerson) );
//...
if ( personCont.Any( Person.EqualsExpressionTree(anotherPerson)) ) {
//...

Кроме того, метод EqualsExpressionTree можно переписать для вызова статического метода Equals, что позволяет использовать собственную логику равенства. Однако помните, что ваш код должен преобразовываться в выражение SQL , поскольку мы, в конце концов, обращаемся к базе данных и не обращаемся к вещам из памяти.

Автор: rmiesen Размещён: 30.05.2014 05:31
Вопросы из категории :
32x32