这可能有点推动了Linq-to-Sql的界限,但考虑到它到目前为止的多样性,我想我会问。
我有3个查询选择相同的信息,只在 where 子句中有所不同,现在我知道我可以传递一个委托,但这只允许我过滤已经返回的结果,但我想通过参数建立查询以确保效率。
以下是查询:
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))
这可能吗?我认为不是,但我想先退房。
由于
答案 0 :(得分:2)
是的。
var times = DataContext.EventDateTimes;
if (cond)
times = times.Where(time => time.StartDate <= ...);
from row in ... join time in times ...
答案 1 :(得分:2)
您可以做的是传递一个允许过滤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>
here(大约40行代码)的实施的源代码以及关于它的博客文章here。
请注意,您的查询比我在此处显示的示例稍微复杂一些,因此定义正确的过滤器可能需要更多的工作。