2010-04-26 101 views
0

这可能会推动Linq-to-Sql的界限,但考虑到它迄今为止的多功能性,我认为我会问。将Linq-to-Sql查询的WHERE子句作为参数传递

我有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

是的。

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

from row in ... join time in times ... 
+0

啊,这看起来可行,我会给它一个去,谢谢。 – Mantorok 2010-04-26 09:55:53

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

请注意,您的查询比我在此处显示的示例稍微复杂一点,因此可能需要更多工作来定义正确的过滤器。