我们如何在Entity Framework中进行对象过滤?

时间:2011-05-16 20:38:34

标签: c# .net entity-framework

定义对象上下文时,首先在实体框架中使用代码,例如:

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”过滤?

4 个答案:

答案 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.FiltersThis post显示了如何使用它。