将Linq-to-Sql查询的WHERE子句作为参数传递

这可能有点推动了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)) orderby time.StartDate select new EventDetails { Title = row.EventName, Description = TrimDescription(row.Description) }; 

我想通过参数应用的代码是:

 time.StartDate = DateTime.Now.Date.AddDays(1)) 

这可能吗? 我认为不是,但我想先退房。

谢谢

是的。

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

你可以做的是传递一个允许过滤IQueryable的对象。 执行此操作时,您可以编写像这样的服务层代码:

 public Person[] GetAllPersons(IEntityFilter filter) { IQueryable query = this.db.Persons; query = filter.Filter(query); return query.ToArray(); } 

在您的调用图层中,您可以像这样定义一个filter:

 IEntityFilter filter = from person in EntityFilter.AsQueryable() where person.Name.StartsWith("a") where person.Id < 100 select person; // or (same result, but without LINQyness) IEntityFilter filter = EntityFilter .Where(p => p.Name.StartsWith("a")) .Where(p => p.Id < 100); // Call the BL with the filter. var persons = BusinessLayer.GetAllPersons(filter); 

您可以在此处找到此EntityFilter的实现的源代码(大约40行代码)以及此处的博客文章。

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