Linq to Sql: я делаю это правильно? - PullRequest
2 голосов
/ 20 июня 2009

Я работаю над проектом уровня доступа к базе данных и решил использовать Linq to SQL для него. Одна из вещей, которые я хотел сделать, - предоставить API, который может использовать выражения Linq в качестве аргументов для извлечения данных. Например, я написал этот API сейчас, который выглядит так:

 public Result GetResults(System.Linq.Expressions.Expression<Func<Result, bool>> predicate)
    {
        Result result = db.Results.SingleOrDefault(predicate);
        return result;
    }

Затем вы можете использовать этот API для запроса к базе данных строки результатов, которая удовлетворяет определенным условиям, например:

Result result = Provider.GetResults(r => r.ID == 11);

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

Следующим шагом было получение нескольких объектов из базы данных.

То, как я заставил его работать, было так:

public List<Result> GetResults(System.Linq.Expressions.Expression<Func<Result, bool>> predicate)
    {
        List<Result> results = db.Results.Select(r => r).Where(r => r.ID == 11).ToList<Result>();
        return results;
    }

Как видите, я вызываю Select с r => r, это возвращает мне все, а затем я использую Where, чтобы отфильтровать то, что мне нужно.

Это работает ... но что-то говорит мне, что я делаю это действительно безобразно. Я могу ошибаться, но разве это не вытаскивает ВСЕ из таблицы результатов, а затем фильтрует? или он собирает правильный оператор SQL, который фильтрует на уровне базы данных?

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

Спасибо!

Ответы [ 2 ]

1 голос
/ 20 июня 2009

Select(r=>r) ничего не делает (кроме изменения с Table<T> на IQueryable<T> - но ничего полезно ). И я предполагаю, что вы намеревались передать predicate на Where?

Действительно, этот не все вытаскивает и фильтрует - генерируется соответствующее предложение WHERE (TSQL). Это возможно из-за «отложенного выполнения» и «компоновки», то есть фактически ничего не выполняется, пока вы не начнете перебирать данные (в ToList()) - до тех пор, пока вы просто не создадите запрос.

Вы можете увидеть это, выполнив что-то вроде:

db.Log = Console.Out;

и посмотрите на TSQL. Или запустите трассировку TSQL. Чтобы сделать его красивее, упростите его до:

return db.Results.Where(predicate).ToList();
0 голосов
/ 20 июня 2009

Я знаю, что вы сказали, что хотите передать предикат и вернуть список, но рассматривали ли вы возможность возврата IQueryable

Тогда вы можете позвонить:

 GetResults().Where(r => r.SomeProperty == "SomeValue")
     .OrderBy(r => r.SomeOtherProperty)
     .Skip(10) 
     .Take(10); //etc. 

С вашим текущим дизайном API вы должны вернуть все записи, а затем получить 10, где, как указано выше, вернется только 10, что вам нужно ...

Просто некоторые мысли ...

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