Linq2DB произвольный пункт Где - PullRequest
0 голосов
/ 27 декабря 2018

Я хотел бы иметь возможность реализовать метод поиска, который может принимать любые произвольные свойства моего класса POCO в качестве аргументов.Это хорошо работает:

 public static IEnumerable<iUser> Search(DataContext context, Func<iUser, bool> predicate)
    {
        return from i in context.GetTable<iUser>().Where(predicate) select i;
    }

, но в этом случае фильтрация происходит после сбора всех строк в таблице.

Можно ли использовать Linq для создания произвольного запроса, напримерэто без фильтрации после вызова sql?Какие подходы вы бы порекомендовали?

Спасибо!

1 Ответ

0 голосов
/ 27 декабря 2018

LINQ to DB - это объектно-реляционный маппер (ORM), способный переводить выражения LINQ в SQL.Слово «выражение» здесь важно.Func - это не выражение, а делегат, вы должны использовать Expression<Func<>> в методах LINQ для LINQ to DB, чтобы иметь возможность их переводить.В противном случае данные сначала извлекаются из базы данных, после чего Func фильтрует их в памяти.

Таким образом, ваша функция должна выглядеть следующим образом:

public static IEnumerable<iUser> Search(DataContext context,
    Expression<Func<iUser, bool>> predicate)
{
    return context.GetTable<iUser>().Where(predicate);
}

Тип возвращаемого значения зависит от того, чтоВы хотите, чтобы вызывающая функция была способна.Если вы вернете IQueryable<iUser>, вызывающая сторона сможет расширить выражение своими собственными выражениями.То есть Search(context, somePredicate).Where(...) будет переведено на SQL в целом.Возвращение IEnumerable будет применять любые последующие предикаты (либо как Func, либо как Expression) в памяти.

Примечание, чтобы выровнять с общими соглашениями об именах, если iUser является интерфейсом (у меня нетидея, если LINQ to DB поддерживает интерфейсы), то вам следует переименовать его в IUser, в противном случае назвать его User.

...