Как провести рефакторинг нескольких похожих запросов Linq-To-Sql? - PullRequest
3 голосов
/ 14 мая 2009

Прочитайте перед понижением или закрытием: Этот почти точный дубликат моего предыдущего вопроса существует с единственной целью перефразировать предыдущий вопрос в область Linq-To-Sql. Все ответы, содержащиеся в предыдущем вопросе, действительны для области Linq, но недопустимы в области Linq-To-SQL.

Предположим, у меня есть два следующих запроса Linq-To-SQL, которые я хочу реорганизовать:

var someValue1 = 0;
var someValue2= 0;
var query1 = db.TableAs.Where( a => a.TableBs.Count() > someValue1 )
              .Take( 10 );
var query2 = db.TableAs.Where( a => a.TableBs.First().item1 == someValue2)
              .Take( 10 );

Обратите внимание, что изменяется только параметр Where. Есть ли способ поместить запрос в метод и передать параметр Where в качестве аргумента?

Все решения, опубликованные в предыдущем вопросе , пытались завершиться неудачно во время выполнения, когда я пытаюсь перечислить результат.

Возникло исключение: «Неподдерживаемая перегрузка, используемая для оператора запроса« Где »»

Ответы [ 2 ]

6 голосов
/ 14 мая 2009

Абсолютно. Вы бы написали:

public IQueryable<A> First10(Expression<Func<A,bool>> predicate)
{
    return db.TableAs.Where(predicate).Take(10);
}

(предполагается, что TableA равно IQueryable<A>.)

Позвоните по номеру:

var someValue1 = 0;
var someValue2= 0;
var query1 = First10(a => a.TableBs.Count() > someValue1);
var query2 = First10(a => a.TableBs.First().item1 == someValue2);

Я верю , что будет работать ...

Разница между этим и ответами на ваш предыдущий вопрос заключается в том, что этот метод принимает Expression<Func<T,bool>> вместо Func<T,bool>, поэтому в итоге он использует Queryable.Where вместо Enumerable.Where.

1 голос
/ 15 мая 2009

Если вы действительно хотите многократного использования, вы можете попробовать написать своих собственных операторов. Например. вместо того, чтобы многократно писать:

var query = 
Products
    .Where(p => p.Description.Contains(description))
    .Where(p => p.Discontinued == discontinued);

Вы можете написать простыми методами:

public static IEnumerable<Product> ByName(this IEnumerable<Product> products, string description)
{
    return products.Where(p => p.Description.Contains(description));
}


public static IEnumerable<Product> AreDiscontinued(IEnumerable<Product> products, bool isDiscontinued)
{
    return products.Where(p => p.Discontinued == discontinued);
}

, а затем используйте его так:

var query = Products.ByName("widget").AreDiscontinued(false);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...