使用泛型方法返回 list其中 T 可以是共享相同结构的三种类型之一

本文关键字:结构 类型 三种 共享 list 返回 泛型方法 其中 | 更新日期: 2023-09-27 18:34:09

>我有一些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 语句中,智能感知抱怨它不能隐式地从特定类型(例如 view1(转换为 T 的泛型列表。 然后,这会阻止我在 lambda 表达式中使用更下方的强类型。

有没有办法实现我想做的事情,或者我在这里吠叫完全错误的树?

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

我还没有完全测试过这一点,但我认为你可以通过创建一个具有属性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
{
}

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

var searchQuery = new List<IAccountTable>();

将实际查询的结果强制转换为接口。

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

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

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

以此类推其他情况...

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