使用通用方法 return list<T> 其中 T 可以是共享相同结构的三种类型之一

Use generic method to return list<T> where T could be one of three types that share the same structure

我有一些 sql 视图使用了不同的源表,但每个视图 return 的结构完全相同。

非常简单:

view1
    select tblA.Name as custName,
           tblA.DOB as DateOfBirth,
           tblA.accountBalance as AccountBalance
    from myFirstTable tblA

view2
    select tblB.AccountName as custName,
           tblB.BirthDate as DateOfBirth,
           tblB.Balance as AccountBalance
    from mySecondTable tblB

view3
    select tblC.CustomerName as custName,
           tblC.DateOfBirth as DateOfBirth,
           tblC.accBal as AccountBalance
    from myThirdTable tblC

因此,即使源表中的字段名不同,不同的视图也会 return 具有相同名称(和类型)的字段。实际视图复杂而庞大,每个视图 运行 数百行。

然后我将这些视图拖到我的 Linq-to-sql 设计器中,并尝试在通用 class.

中使用它们
    public static List<T> MainSearch<T>(ReportParams RP)
    {
        MyDataContext dc = new MyDataContext();

        if (string.IsNullOrEmpty(RP.appType)) { return null; }

        var searchQuery = new List<T>();

        switch (RP.appType)
        {
            case "type1":
                searchQuery = (from t in dc.view1s select t);
                break;
            case "type2":
                searchQuery = (from t in dc.view2s select t);
                break;
            case "type3":
                searchQuery = (from t in dc.view3s select t);
                break;
        }

        //do other stuff with search query depending on params
        DateTime dtFrom = Convert.ToDateTime(RP.fromDate);
        searchQuery = searchQuery.Where(q => convert.ToDateTime(q.DateOfBirth) >= dtFrom);

        //and so on...

想法是可以使用通用前端根据用户选择传入参数,然后使用这些参数缩小要搜索的特定源数据的搜索结果(永远不会是组合 returned,它始终是三种视图中的一种。

上面的代码不起作用。在我的 switch 语句中,intellisense 抱怨它不能从特定类型(例如 view1)隐式转换为 T 的泛型列表。这阻止了我在 lambda 表达式中进一步使用强类型。

有什么方法可以实现我想要做的事情,还是我在这里完全找错了树?

在 Entity Framework 中,正确的方法是创建一个单独的 TBaseclass,即 T1T2T3将派生自。它将包含您需要的所有通用属性,因此不需要 switch 语句:您只需要 TBase someObj; 然后就可以直接使用 someObj.ACommonProperty

如果您的 class 具有与视图返回的相同属性集,那么您可以尝试这样的操作:

case "type1":
searchquery = (from t in dc.view1s select new commonClass() { CustName = t.CustName, DateOfBirth = t.DateOfBirth, AccountBalance = t.AccountBalance });
                break;

其他情况依此类推...

我还没有对此进行全面测试,但我认为您可以通过创建一个具有属性 custName、DOB 和 AccountBalance 的接口来实现。然后让每个生成的 LINQ-to-SQL classes (tblA, tblB, tblC) 在单独的部分 class 文件中实现此接口。只要 属性 名称和类型匹配就应该没问题。

interface IAccountTable
{
    string custName { get; set; }
    DateTime DOB { get; set; }
    Decimal AccountBalance { get; set; }
}

partial class tblA : IAccountTable
{
}

使您的搜索查询成为该接口的列表。

var searchQuery = new List<IAccountTable>();

将您实际查询的结果投射到界面。

searchQuery = tblA.Where(t => t.custName == "Uday").Select(t => (IAccountTable)t).ToList();