对多个实体类型使用LINQ to Entities扩展方法
本文关键字:to LINQ Entities 扩展 方法 实体 类型 | 更新日期: 2023-09-27 17:59:05
我有以下扩展方法:
public static IQueryable<Employee> WhereStatus(this IQueryable<Employee> queryable, string status)
{
var result = queryable
.Where(e => e.EmployeeStatus.Where(s => s.StatusEndDate == null).Select(s => s.Status)
.FirstOrDefault() == status);
return result;
}
public static IQueryable<Employee> WhereCostCenter(this IQueryable<Employee> queryable, int costCenterID)
{
var result = queryable
.Where(e => e.CostCenterID == costCenterID);
return result;
}
我几乎在每个LINQ查询中都需要这些扩展方法,以根据几个参数(例如:状态、成本中心、性别等)将查询筛选到特定的员工
using (DB db = new DB())
{
var emps = from em in db.Employees
.WhereStatus("Active")
.WhereCostCenter(112)
select em.EmpID;
var courses = from cr in db.Courses
where c.Contains(cr.EmpID)
select cr;
// now I have the filtered list of the courses I want
.....
}
问题:这是最佳做法吗?或者有没有一种方法可以使扩展方法适用于我拥有的所有实体类型,因为所有实体都有一个EmpID?类似于:
var courses = from em in db.Courses
.WhereStatus("Active") // use the extension methods directly here as well
.WhereCostCenter(112)
select cr;
问题是并非所有实体都具有使用所有扩展方法所需的属性。您可以做的是创建属性的子集,并将它们放置到接口中。
示例:
public interface IHaveCostCenterID
{
public int CostCenterID {get; set;}
}
public partial class Employee : IHaveCostCenterID
{
}
public partial class Department : IHaveCostCenterID
{
}
public static IQueryable<IHaveCostCenterID> WhereCostCenter(this IQueryable<IHaveCostCenterID> queryable, int costCenterID)
{
var result = queryable
.Where(e => e.CostCenterID == costCenterID);
return result;
}
另一种方式:
public static class Extension
{
public static IQueryable<TEntity> WhereCostCenter<TEntity>(
this IQueryable<TEntity> queryable, int costCenterID)
where TEntity : IHaveCostCenterID
{
var result =
queryable.Where(e => e.CostCenterID == costCenterID);
return result;
}
}
public interface IHaveCostCenterID
{
int CostCenterID { get; set; }
}
public partial class Employee : IHaveCostCenterID
{
public int CostCenterID { get; set; }
}
public partial class Department : IHaveCostCenterID
{
public int CostCenterID { get; set; }
}
这可以是一种使用通用方法提取公共代码的解决方案,而不仅仅是针对LINQ。只要您有两段(或更多)相同的代码,除了它们碰巧使用不同的类之外,您就可以这样做。将公共部分提取到接口中,并使泛型方法使用接口约束。