定义对象上下文时,首先在实体框架中使用代码,例如:
public class DomainContext : DbContext
{
public DomainContext() { }
public virtual DbSet<News> News { get; set; }
}
我们都知道你可以查询“新闻”做类似事情(例如,获取今天发布的所有新闻):
var ctx = new DomainContext();
ctx.News.Where(x => x.PublishedDate == DateTime.Now.Date)
但是,这就是问题:是否有办法将预定义的过滤/条件应用于通过ctx.News
的所有查询?假设我希望ctx.News
上的所有查询都隐式应用“Published Today”过滤?
答案 0 :(得分:3)
无法添加自动条件(过滤器)来查询新闻。所有发布的示例都有效,但前提是您直接查询News
。例如,如果您加载指向News
的导航属性,示例将失败。
EDMX通过conditional mapping解决了这个问题,但这导致了其他非常糟糕的缺点。条件映射是固定的(如果没有重建模型就无法更改),并且每种类型只能有一个条件 - 就像TPH降级为单个实体类型一样。此外,条件映射中定义的条件可能不适用于“今天”。条件映射在代码优先方法中不可用。
答案 1 :(得分:2)
我不相信有一种方法可以像你建议的那样为DbSet<News>
对象添加过滤器。但你应该做的只是写另一个函数:
public virtual IEnumerable<News> TodaysNews
{
get { return News.WHere(n => n.PublishDate == DateTime.Today); }
}
然后,我想,如果你在其他地方做了一个查询,比如:
var todaysGoodNews = from n in ctx.TodaysNews
where n.IsGood == true
select n;
然后它会在将查询发送到服务器时合并查询,而不是将它作为两个单独的查询。如果你使用IEnumerable<>
或者你需要返回别的东西(IQueryable<>
,或许可以吗?),那么我不肯定。
修改强>
我刚刚看到你对下面另一张海报的回复。我想我花了太长时间打字/格式化。我不知道有任何方法可以应用这样的过滤器,但有效的做法不是我们的解决方案吗?你甚至可以让TodaysNews成为通过上下文或其他东西直接访问该对象的唯一方法。
答案 2 :(得分:0)
您可以在上下文中添加新属性:
public IEnumerable<News> TodaysNews
{
get
{
return this.News.Where(x => x.PublishedDate == DateTime.Now.Date);
}
}
然后可以对属性应用任何进一步的过滤/排序/等。
<强>更新强>
如果您无法仅使用预过滤的查询,则另一个选项是在数据库中创建视图并将您的实体映射到该视图。视图可以基于当前日期。
答案 3 :(得分:0)
我遇到了同样的问题,我发现了这个问题:EntityFramework.Filters。 This post显示了如何使用它。