ASP.NET веб-формы Выпадающий список из API [дубликат]

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

Взгляните на https: // posithub.org/, который демонстрирует тип номера, называемый posit (и его предшественник unum), который обещает предложить лучшую точность с меньшим количеством бит. Если мое понимание верное, оно также фиксирует проблемы в вопросе. Весьма интересный проект, человек, стоящий за ним, является математиком Dr. Джон Густафсон . Все это с открытым исходным кодом, с множеством реализаций в C / C ++, Python, Julia и C # ( https://hastlayer.com/arithmetics ).

30
задан Hakam Fostok 19 February 2016 в 11:45
поделиться

6 ответов

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

Возможно, он фактически не получает данные, пока вы его не используете (это ленивая загрузка), поэтому dataContext не существует, когда вы пытаетесь выполнить эту работу. Бьюсь об заклад, если бы вы сделали ToList () в области видимости, это было бы нормально.

try
{
    IQueryable<User> users;
    var ret = null;

    using (var dataContext = new dataContext())
    {
        users = dataContext.Users.Where(x => x.AccountID == accountId && x.IsAdmin == false);

        if(users.Any())
        {
            ret = users.Select(x => x.ToInfo()).ToList(); 
        }

     }

   Return ret;
}
catch (Exception ex)
{
    ...
}
30
ответ дан Community 5 September 2018 в 11:01
поделиться

Измените это:

using (var dataContext = new dataContext())
{
    users = dataContext.Users.Where(x => x.AccountID == accountId && x.IsAdmin == false);

    if(users.Any())
    {
        ret = users.Select(x => x.ToInfo()).ToList(); 
    }

 }

на это:

using (var dataContext = new dataContext())
{
    return = dataContext.Users.Where(x => x.AccountID == accountId && x.IsAdmin == false).Select(x => x.ToInfo()).ToList();
} 

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

1
ответ дан ComeIn 5 September 2018 в 11:01
поделиться

Это может быть так же просто, как добавить ToList () в ваш репозиторий. Например:

public IEnumerable<MyObject> GetMyObjectsForId(string id)
{
    using (var ctxt = new RcContext())
    {
        // causes an error
        return ctxt.MyObjects.Where(x => x.MyObjects.Id == id);
    }
}

приведет к обнаружению Db Context в вызывающем классе, но это может быть разрешено путем явного осуществления перечисления путем добавления ToList () в операции LINQ:

public IEnumerable<MyObject> GetMyObjectsForId(string id)
{
    using (var ctxt = new RcContext())
    {
        return ctxt.MyObjects.Where(x => x.MyObjects.Id == id).ToList();
    }
}
1
ответ дан Grant Cermak 5 September 2018 в 11:01
поделиться

Вы должны помнить, что запросы IQueryable фактически не выполняются в хранилище данных, пока вы не перечислите их.

using (var dataContext = new dataContext())
{

Эта строка кода фактически не делает ничего, кроме сборки SQL-оператора

    users = dataContext.Users.Where(x => x.AccountID == accountId && x.IsAdmin == false);

. Any () - операция, которая перечисляет IQueryable, поэтому SQL отправляется в источник данных (через dataContext), а затем выполняется против него действие .Any ()

    if(users.Any() == false)
    {
        return null;
    }
}

. Ваша строка «проблема» повторно использует построенный выше sql, а затем выполняет дополнительная операция (.Select ()), которая просто добавляет к запросу. Если вы оставили его здесь, никакое исключение, кроме вашей проблемной строки

return users.Select(x => x.ToInfo()).ToList(); // this line is the problem

, вызывает .ToList (), который перечисляет IQueryable, что приводит к отправке SQL-кода в источник данных с помощью используемого dataContext в исходном запросе LINQ. Поскольку этот dataContext был удален, он уже недействителен, и .ToList () выдает исключение.

Это «почему он не работает». Исправление состоит в том, чтобы переместить эту строку кода в область вашего объекта dataContext.

Как правильно использовать его - это еще один вопрос с несколькими, возможно, правильными ответами, которые зависят от вашего приложения (Forms vs. ASP.net vs MVC и т. Д.). Образцом, который это реализует, является шаблон Единицы работы. Для создания нового объекта контекста практически нет затрат, поэтому общее правило состоит в том, чтобы создать его, выполнить свою работу и затем избавиться от него. В веб-приложениях некоторые люди создадут контекст для каждого запроса.

13
ответ дан Joe Enzminger 5 September 2018 в 11:01
поделиться

Здесь вы пытаетесь выполнить объект IQueryable в неактивном DBContext. ваш DBcontext уже удален. вы можете выполнить только объект IQueryable до удаления DBContext. Значит, вам нужно написать инструкцию users.Select(x => x.ToInfo()).ToList() внутри с помощью области

1
ответ дан Niraj Trivedi 5 September 2018 в 11:01
поделиться

Объекты, выставленные как IQueryable<T> и IEnumerable<T>, фактически не выполняются до тех пор, пока они не будут повторены или иным образом недоступны, например, составлены в List<T>. Когда EF возвращает IQueryable<T>, он по существу просто создает что-то, способное извлекать данные, оно фактически не выполняет извлечение, пока вы его не уничтожаете.

Вы можете почувствовать это, поставив точку останова, где IQueryable определяется, когда вызывается .ToList(). (Изнутри контекста данных, как правильно указал Jofry.) Работа по извлечению данных выполняется во время вызова ToList().

Из-за этого вам нужно сохранить IQueryable<T> в рамках контекста данных.

24
ответ дан Steve Py 5 September 2018 в 11:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: