简体   繁体   English

对多个实体类型使用LINQ to Entities扩展方法

[英]Using LINQ to Entities extension methods for more than one entity type

I have the following extension methods: 我有以下扩展方法:

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;
}

I need these extension methods almost in every single LINQ query to filter the query to certain employees depending on few parameters (for example: status, cost center, gender...etc). 我几乎在每个LINQ查询中都需要这些扩展方法,以根据几个参数(例如:状态,成本中心,性别等等)将查询过滤到某些员工。 Right now I am using it like this: 现在我正在使用它:

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
      .....
}

Question: Is that the best practice? 问题:这是最佳做法吗? or is there a way to make the extension method works with all entity types I have since all entities have an EmpID? 或者有没有办法让扩展方法适用于我拥有的所有实体类型,因为所有实体都有一个EmpID? something like: 就像是:

var courses = from em in db.Courses
              .WhereStatus("Active")    // use the extension methods directly here as well
              .WhereCostCenter(112)
              select cr;

The problem is that not all of the entities will have the properties necessary to use all of the extension methods. 问题是并非所有实体都具有使用所有扩展方法所必需的属性。 What you can do is create subsets of the properties, and place them into interfaces. 您可以做的是创建属性的子集,并将它们放入接口。

Example: 例:

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;
}

Another way: 其他方式:

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; }
}

This can be a solution to use of generic methods to extract common code, and not just for LINQ. 这可以是使用泛型方法来提取公共代码的解决方案,而不仅仅是LINQ。 You can do this whenever you have two (or more) pieces of code which are identical except that they happen to use different classes. 只要你有两个(或更多)相同的代码片段,除了碰巧使用不同的类之外,你可以这样做。 Extract the common part into interfaces, and have the generic method use an interface constraint. 将公共部分提取到接口中,并使通用方法使用接口约束。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM