【问题标题】:How to set filter option on DbSet property in Entity Framework?如何在实体框架中的 DbSet 属性上设置过滤器选项?
【发布时间】:2020-04-13 01:00:21
【问题描述】:

我的上下文类中有一个DbSet 属性,如下所示:

public class ProjectContext: DbContext
{
    public ProjectContext(): base("name=DBCS")
    {
    }

    public DbSet<Employee> EmployeeDbSet { get; set; }
}

我的项目的许多地方都在使用此属性。现在我需要在Employee 上设置一个通用条件,例如我只需要在职员工。我可以通过简单地过滤我的 linq 查询来获得活跃的员工:

var employees = context.EmployeeDbSet.where(e => e.IsActive).ToList();

由于我已经在项目的许多地方编写了许多查询,现在我必须全部重写它们,这非常困难、耗时且容易出错。

由于这是一个通用条件,我想在所有查询中设置它,我正在寻找一种方法来设置EmployeeDbSet 属性的条件。

可以实现吗?

【问题讨论】:

  • 关于通用 EF 方法的 SO 上有很多答案:例如,请参阅 here

标签: c# asp.net-mvc entity-framework


【解决方案1】:

您可以将IQueryable&lt;Employee&gt; 属性添加到您的 DbContext 以返回活动的 where 条件集。

示例;

public IQueryable<Employee> ActiveEmployees 
{
    get
    {
        return EmployeeDbSet.Where(e => e.IsActive);
    }
}

这样你就可以将它与其他 where 条件结合起来,只需做;

context.ActiveEmployees.Where(x=> x.name == "john");

执行此操作后,您将无法使用直接在 DbSet&lt;T&gt; 中声明的方法。使用 where 后要使用 find 方法,您可以自己添加一个新的 find 方法,如下所示;

public static class DbModelExtensions
{
    public static Employee Find(this IQueryable<Employee> query, int id)
    {
        return query.Where(x => x.Id == id).FirstOrDefault();
    }
}

如果当前文件中引用了 IQueryable&lt;Employee&gt; 的命名空间,则这会将扩展方法 Find 添加到仅IQueryable&lt;Employee&gt;

那你就可以这样使用了;

context.ActiveEmployees.Find(15);

【讨论】:

  • 我已经在许多查询和加入中使用了我现有的EmployeeDbSet。根据您的建议,我将EmployeeDbSet 重命名为Employees 并添加了IQueryable&lt;Employee&gt; EmployeeDbSet。但我面临一个小问题,IQuerable 不支持Find 方法。如果我用First 替换Find,一切都会按预期进行。但是恐怕我可以在 DbSet 提供的IQuerable 上使用所有必要的扩展方法。你能解释一下吗?
  • 使用 IQueryable 时,您可以使用 linq 提供的所有方法。但 Find 是直接在 DbSet 类本身上声明的特殊方法。所以你用了 where 后就不能再用了
  • 非常感谢您抽出宝贵的时间。这对我帮助很大。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-04
  • 1970-01-01
相关资源
最近更新 更多