Поддерживаются только инициализаторы, сущности и свойства навигации сущности

Я получаю это исключение:

Указанный член типа 'Paid' не поддерживается в LINQ to Entities. Только инициализаторы, сущности и свойства навигации сущности поддерживаются.

    public ActionResult Index()
    {
        var debts = storeDB.Orders
            .Where(o => o.Paid == false)
            .OrderByDescending(o => o.DateCreated);

        return View(debts);
    }

Мой класс модели

public partial class Order
{
    public bool Paid {
        get {
            return TotalPaid >= Total;
        }
    }

    public decimal TotalPaid {
        get {
            return Payments.Sum(p => p.Amount);
        }
    }

Платежи - это Связанная таблица, содержащая сумму поля. Запрос работает, если я удаляю предложение Where, показывающее правильную информацию о платежах, подскажите, что не так с кодом?

Решенный как ответ, предложенный с помощью

    public ActionResult Index()
    {
        var debts = storeDB.Orders
            .OrderByDescending(o => o.DateCreated)
            .ToList()
            .Where(o => o.Paid == false);

        return View(debts);
    }

Ответ 1

Entity пытается преобразовать ваше свойство Paid в SQL и не может, потому что оно не является частью схемы таблицы.

Что вы можете сделать, так это позволить Entity запросить таблицу без фильтра Paid и затем отфильтровать не оплаченные.

public ActionResult Index()
{
    var debts = storeDB.Orders
        //.Where(o => o.Paid == false)
        .OrderByDescending(o => o.DateCreated);

    debts = debts.Where(o => o.Paid == false);

    return View(debts);
}

Это, конечно, означало бы, что вы возвращаете все данные на веб-сервер и фильтруете данные на нем. Если вы хотите отфильтровать сервер БД, вы можете создать расчетный столбец в таблице или использовать хранимую процедуру.

Ответ 2

Просто пришлось решить подобную проблему. Для решения выше требуется обработка в памяти, что является плохой практикой (ленивая загрузка).

Мое решение состояло в том, чтобы написать помощника, который вернул предикат:

public static class Extensions
{
    public static Expression<Func<Order, bool>> IsPaid()
    {
        return order => order.Payments.Sum(p => p.Amount) >= order.Total;
    }
}

Вы можете переписать свой оператор linq как:

var debts = storeDB.Orders
                    .Where(Extensions.IsPaid())
                    .OrderByDescending(o => o.DateCreated);

Это удобно, если вы хотите повторно использовать логику расчета (DRY). Недостатком является то, что логика не в вашей модели домена.

Ответ 3

Linq преобразует операторы в операторы SQL и выполняет их в базы данных.

Теперь это преобразование происходит только для членов сущностей, инициализаторов и свойств навигации сущности. Таким образом, чтобы достичь функции или получить сравнение свойств, нам нужно сначала преобразовать их в список в памяти, а затем применить функцию для извлечения данных.

Поэтому в совокупности

var debts = storeDB.Orders.toList()
        .Where(o => o.Paid == false)
        .OrderByDescending(o => o.DateCreated);

Ответ 4

Эта проблема также может возникать из свойства [NotMapped], которое имеет одно и то же имя в вашей модели базы данных и модели просмотра.

AutoMapper пытается выбрать его из БД во время проекции; и свойство NotMapped, очевидно, не существует в БД.

Решением является Ignore свойство в конфигурации AutoMapper при сопоставлении из модели БД модели View.

  • Ищите свойство [NotMapped] с именем Foo в вашей модели DB.
  • Ищите свойство с тем же именем, Foo, в вашей модели просмотра.
  • Если это так, измените конфигурацию AutoMapper. Добавить .ForMember(a => a.Foo, b => b.Ignore());

Ответ 5

Другая вероятная причина в том, что вы используете IEnumerable для вашей собственности вместо ICollection

Так что вместо:

public class This
{
    public long Id { get; set; }
    //...
    public virtual IEnumerable<That> Thats { get; set; }
}

Сделай это:

public class This
{
    public long Id { get; set; }
    //...
    public virtual ICollection<That> Thats { get; set; }
}

И ты чертовски дорогая... глупая вещь, чтобы потерять 2 часа.

Ответ 6

Такая ситуация также может возникнуть, если вы используете неподдерживаемые типы EntityFramework, такие как unsigned int.

Это был мой случай такой ошибки.

Ознакомьтесь с дополнительной информацией о поддерживаемых типах: https://msdn.microsoft.com/en-us/library/ee382832(v=vs.100).aspx

Для таких ситуаций есть обходной путь, объясненный GFoley83: Как использовать типы без знака int/long с Entity Framework?

Ответ 7

Я столкнулся с этой проблемой, потому что имел переменную-член только с get without set свойство

что означает его auto calculated и not stored в качестве столбца в the table

поэтому его not exist в table schema

так make sure, что любая переменная-член not auto calculated to have a getter и setter свойства

Ответ 8

у вашего edmx и контекстной модели есть какое-то другое свойство diffrent, которое добавляется в db.

Обновите свой EDMX, обновите его правильно, Bulid ваш проект и запустите снова.

Это решит вашу проблему.

С уважением, Ганеш Никам