1

次の拡張メソッドがあります。

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

1 に答える 1

3

問題は、すべてのエンティティがすべての拡張メソッドを使用するために必要なプロパティを持っているわけではないということです。できることは、プロパティのサブセットを作成し、それらをインターフェイスに配置することです。

例:

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 だけでなく、ジェネリック メソッドを使用して一般的なコードを抽出するためのソリューションになる可能性があります。たまたま異なるクラスを使用していることを除いて同一のコードが 2 つ (またはそれ以上) ある場合はいつでも、これを行うことができます。共通部分をインターフェイスに抽出し、ジェネリック メソッドにインターフェイス制約を使用させます。

于 2013-02-13T02:26:13.543 に答える