Передача предложения WHERE для запроса Linq-to-Sql в качестве параметра - PullRequest
0 голосов
/ 26 апреля 2010

Это, вероятно, немного раздвигает границы Linq-to-Sql, но учитывая, насколько универсальным он был до сих пор, я подумал, что спрошу.

У меня есть 3 запроса, которые выбирают одинаковую информацию и отличаются только в предложении , где , теперь я знаю, что могу передать делегата, но это позволяет только отфильтровать уже возвращенные результаты, но я хочу создать запрос через параметр для обеспечения эффективности.

Вот запрос:

from row in DataContext.PublishedEvents
join link in DataContext.PublishedEvent_EventDateTimes
    on row.guid equals link.container
join time in DataContext.EventDateTimes on link.item equals time.guid
where row.ApprovalStatus == "Approved"
    && row.EventType == "Event"
    && time.StartDate <= DateTime.Now.Date.AddDays(1)
    && (!time.EndDate.HasValue || time.EndDate.Value >= DateTime.Now.Date.AddDays(1))
orderby time.StartDate
select new EventDetails
{
    Title = row.EventName,
    Description = TrimDescription(row.Description)
};

Код, который я хочу применить с помощью параметра, будет:

time.StartDate <= DateTime.Now.Date.AddDays(1) &&
(!time.EndDate.HasValue || time.EndDate.Value >= DateTime.Now.Date.AddDays(1))

Возможно ли это? Я не думаю, что это так, но думал, что я проверю сначала.

Спасибо

Ответы [ 2 ]

2 голосов
/ 26 апреля 2010

Что вы можете сделать, это передать объект, который позволяет фильтровать IQueryable. Когда вы сделаете это, вы можете написать код так, как будто это ваш сервисный уровень:

public Person[] GetAllPersons(IEntityFilter<Person> filter)
{
    IQueryable<Person> query = this.db.Persons;

    query = filter.Filter(query);

    return query.ToArray();
}

и в вашем вызывающем слое вы можете определить фильтр следующим образом:

IEntityFilter<Person> filter =
    from person in EntityFilter<Person>.AsQueryable()
    where person.Name.StartsWith("a")
    where person.Id < 100
    select person;

// or (same result, but without LINQyness)
IEntityFilter<Person> filter = EntityFilter<Person>
    .Where(p => p.Name.StartsWith("a"))
    .Where(p => p.Id < 100);

// Call the BL with the filter.
var persons = BusinessLayer.GetAllPersons(filter);

Вы можете найти исходный код реализации этого EntityFilter<T> здесь (это около 40 строк кода) и в блоге об этом здесь .

Обратите внимание, что ваш запрос немного сложнее, чем приведенный здесь пример, поэтому для определения правильного фильтра может потребоваться немного больше работы.

2 голосов
/ 26 апреля 2010

Да, это так.

var times = DataContext.EventDateTimes;
if (cond)
    times = times.Where(time => time.StartDate <= ...);

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