смешивая базу данных и объектный запрос в linq и предоставляя постраничные результаты - PullRequest
2 голосов
/ 22 декабря 2011

Мне нужно создать запрос, который предоставляет постраничные результаты. Часть фильтрации происходит в базе данных, а часть - в объектах, находящихся в памяти.

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

    Things.Where(e=>e.field1==1 && e.field2>1).ToList()
            .Where(e=>Helper.MyFilter(e,param1,param2)).Skip(m*pageSize).Take(pageSize);

Функция MyFilter использует дополнительные данные, которых нет в базе данных, и она запускается с дополнительными параметрами (paramX в приведенном выше примере)

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

Ответы [ 3 ]

1 голос
/ 22 декабря 2011

Для поддержки ответа Джейсона выше - платформа сущностей поддерживает .Skip (). Take ().Поэтому отправьте все это на уровень БД и преобразуйте ваше местоположение во что-то, что EF может потреблять.

Если ваш помощник сложен, используйте построитель предикатов Албахари:

http://www.albahari.com/nutshell/predicatebuilder.aspx

или немного более простой в использовании Универсальный построитель предикатов:

http://petemontgomery.wordpress.com/2011/02/10/a-universal-predicatebuilder/ на основании вышеизложенного.

1 голос
/ 22 декабря 2011

да, запрос и страница на уровне базы данных. какая бы логика не была в Helper.MyFilter должен быть в запросе sql.

другой вариант, который более навязчив к вашей кодовой базе. сохранить модель представления, а также объект домена при изменении объекта. часть модели представления будет содержать результат Helper.MyFilter(e), чтобы вы могли быстро и эффективно запросить его.

0 голосов
/ 22 декабря 2011
.ToList()

Вы преобразуете свой запрос в объект памяти, т.е. список, и, таким образом, вызываете выполнение запроса, а затем предоставляете подкачку данных.

Вы можете поместить все это в одно Where предложение:

Things.Where(e=>e.field1==1 && e.field2>1
            && e=>Helper.MyFilter(e)).Skip(m*pageSize).Take(pageSize);

, а затем .ToList(). Таким образом, вы дадите Linq для Sql возможность сгенерировать запрос и получить только те данные, которые вам нужны.

Или есть конкретная причина, почему вы хотите сделать именно это - преобразование в объект памяти и затем фильтрацию? Хотя я не вижу в этом смысла. Вы должны иметь возможность отфильтровывать результаты, которые вам не нужны, в запросе Linq to Sql, прежде чем вы фактически выполните его для базы данных.

EDIT

Как я вижу из обсуждения, у вас есть несколько вариантов.

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

Или вы можете выбрать другой подход. Вы можете поместить Helper класс в отдельную сборку и ссылаться на эту сборку из SQL Server . Это позволит вам разместить логику подкачки в вашей базе данных, а также использовать ваш код.

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