#asp.net #asp.net-mvc #linq #entity-framework #iqueryable
#asp.net #asp.net-mvc #linq #entity-framework #iqueryable
Вопрос:
У меня есть ASP.NET Веб-сайт MVC 5 / Entity Framework, на котором пользователь сайта может создавать сложные запросы, сортировать / фильтровать их и т. Д. По группе пользователей / элементов и т. Д. Однако мне нужен способ поддерживать «состояние» запроса между циклами страниц, отправлять их на другие страницы для дальнейших манипуляций и т.д. Вот несколько подходов, которые я рассмотрел:
-
Преобразовать весь результат запроса в IEnumerable (или list): это было бы крайне неэффективно, поскольку мне нужно загружать и перечислять ВСЕХ пользователей списка в памяти, где мне может понадобиться только очень небольшое их подмножество (я использую разбивку на страницы).
-
Преобразуйте запрос в необработанный SQL с помощью
ToString
метода. Однако, таким образом, хотя я могу разбивать страницы на страницы и запрашивать, я все равно теряю возможность редактировать запрос. -
Оставьте
IQueryable
объект как есть, где-нибудь в памяти, чтобы использовать его на следующей странице / запросе и т.д.. Это, помимо того, что является очень плохой / неэффективной практикой, сделало бы объект непригодным для использования из-за того, что IQueryable возвращается в контексте базы данных (DbContext
), поэтому будет недействительным после удаления контекста.
Какова наилучшая практика поддержания «состояния» объекта запроса между жизненными циклами страницы? Принимаются решения как на стороне сервера, так и на стороне клиента, если они соответствуют моим требованиям (не загружать всю базу данных в память, возможность изменять запрос после выполнения, разбивка на страницы, сортировка …)
Комментарии:
1. Разделите запрос и его спецификации . Вы можете сохранить спецификации и повторно применить их к телу запроса.
Ответ №1:
Я не уверен, как вы сейчас «редактируете» IQueryable. Поскольку вы не можете отменить части «внутри» IQueryable, это кажется мне невозможным.
ИМХО, вам нужно разделить определение запроса и выполнение запроса.
Определение, которое я бы сохранил в пользовательском решении. Это может быть что угодно, определите некоторый класс для хранения пользовательского запроса, он, вероятно, будет содержать какую-то коллекцию, чтобы представлять в памяти то, что пользователь видит в представлении.
Для выполнения запроса вам нужно будет преобразовать пользовательский запрос в реальный запрос, который вы можете выполнить в базе данных. Это может быть необработанный SQL, но IQueryable так же хорош.
Если вы сделаете пользовательский запрос сериализуемым, что не должно быть проблемой, поскольку вы определяете его самостоятельно, вы можете просто сохранить сериализованное «состояние» на странице, например, скрытое поле.
Вам также фактически не нужен объект IQueryable, пока вы не захотите выполнить запрос.
Комментарии:
1. Под «редактированием» я подразумеваю представление запроса, а на другой странице — изменение части запроса (и, если последнее менее ограничительно, очевидно, повторный переход к базе данных)