Поддерживаются только инициализаторы, элементы сущностей и свойства навигации сущностей. - PullRequest
96 голосов
/ 03 августа 2011

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

Указанный член типа «Оплачено» не поддерживается в 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);
        }
    }

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

Решено как ответ, предложенный с:

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

        return View(debts);
    }

Ответы [ 8 ]

109 голосов
/ 03 августа 2011

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

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

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);
}

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

23 голосов
/ 03 февраля 2015

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

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

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);

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

15 голосов
/ 18 апреля 2013

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

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

Следовательно, в совокупности,

var debts = storeDB.Orders.toList()
        .Where(o => o.Paid == false)
        .OrderByDescending(o => o.DateCreated);
14 голосов
/ 21 июня 2016

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

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

Решение заключается в Ignore свойстве в конфигурации AutoMapper при отображении из модели DB в модель представления.

  1. Найдите свойство [NotMapped] с именем Foo в вашей модели БД.
  2. Найдите свойство с тем же именем, Foo, в вашей View Model.
  3. Если это так, измените конфигурацию AutoMapper. Добавить .ForMember(a => a.Foo, b => b.Ignore());
11 голосов
/ 07 октября 2015

Другая вероятная причина в том, что вы используете 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 часа.

2 голосов
/ 04 июня 2018

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

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

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

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

0 голосов
/ 15 апреля 2019

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

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

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

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

0 голосов
/ 16 ноября 2016

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...