使用泛型方法返回列表<t>,其中T可以是共享相同结构的三种类型之一

时间:2016-02-11 16:05:36

标签: c# linq-to-sql

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

非常简单:

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

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

然后我将这些视图拖到我的Linq-to-sql设计器中,并尝试在泛型类中使用它们。

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

这个想法是可以使用通用前端根据用户选择传入参数,然后这些参数用于缩小搜索到的特定源数据的搜索结果(它永远不会是返回的组合,它总是三种观点中的一种或另一种。)

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

有没有办法实现我想要做的事情,还是我在这里完全错误地咆哮?

3 个答案:

答案 0 :(得分:2)

如果你的某个类具有与视图返回的相同的属性集,那么你可以尝试这样的事情:

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

以及其他案例......

答案 1 :(得分:2)

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

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

partial class tblA : IAccountTable
{
}

使您的searchQuery成为该界面的列表。

var searchQuery = new List<IAccountTable>();

将实际查询的结果转换为界面。

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

答案 2 :(得分:-1)

在实体框架中,正确的方法是创建一个单独的TBase类,T1T2T3将派生出来。它将包含您需要的所有常用属性,因此不需要switch语句:您只需TBase someObj;,然后就可以直接使用someObj.ACommonProperty