如何创建一个返回IEnumerable匿名类型的方法

时间:2015-01-08 14:04:04

标签: c# linq generics anonymous-types

在我们的环境中,我们有很多大型业务对象。我们使用自己的数据库访问层(在此示例中简化为'Db'类)。有时,我们希望检索业务对象中可用属性的选定部分的列表(例如,仅查看客户的ID和姓氏)。

在实体框架中,我可以使用以下内容:

var keyValues = context<Customer>.Select(c => new { Id = c.ID, LastName = c.LastName, City = c.City })

但正如我之前所说,我们不使用Entity FrameWork,而是使用我们自己的数据访问对象。在本例中,我创建了一个数据库对象'Db'和一个可用于从数据库中获取数据的静态类(现在只支持一种类型的数据对象):

class Db
{
    public static IEnumerable<T> GetData<T>() {
        if (typeof(T) == typeof(DataClass))
        {
            IEnumerable<DataClass> items = new DataClass[] {
                new DataClass { IntValue1 = 101, IntValue2 = 102, StringValue1 = "1_1", StringValue2 = "1_2" },
                new DataClass { IntValue1 = 201, IntValue2 = 202, StringValue1 = "2_1", StringValue2 = "2_2" },
                new DataClass { IntValue1 = 301, IntValue2 = 302, StringValue1 = "3_1", StringValue2 = "3_2" },
                new DataClass { IntValue1 = 401, IntValue2 = 402, StringValue1 = "4_1", StringValue2 = "4_2" },
                new DataClass { IntValue1 = 501, IntValue2 = 502, StringValue1 = "5_1", StringValue2 = "5_2" }
            };
            return items as IEnumerable<T>;
        }
        // else
        return Enumerable.Empty<T>();
    }
}

从数据库中获取数据:

static class DataList <TSource>
{
    public static IEnumerable<TSource> GetList() {
        return Db.GetData<TSource>();
    }

}

使用的数据对象如下所示:

class DataClass
{
    public int IntValue1 { get; set; }
    public int IntValue2 { get; set; }
    public string StringValue1 { get; set; }
    public string StringValue2 { get; set; }
}

然后我希望能够做到这样的事情:

var items = DataList<DataClass>.GetList(x => new { Value1 = x.IntValue1 });

我首先看一下提供相同功能的'Select'Linq扩展方法的方法签名,并在'DataList'类中创建了以下方法。

public static IEnumerable<TResult> GetList<TSource, TResult>(Func<TSource, TResult> selector)
    {
        IEnumerable<TSource> data = Db.GetData<TSource>();

        return data.Select(selector);
    }

让我们忘记在这个例子中,我首先从数据库中获取完整的数据集,然后才通过只选择一个属性到匿名对象来简化数据集。

然而,事情是,上述解决方案不起作用。我在下面的行中收到编译器错误:

var items = DataList<DataClass>.GetList(x => new { Value1 = x.IntValue1 });

错误是:

  

*错误2无法从用法中推断出方法'AnonymousTypeTest.DataList.GetList(System.Func)'的类型参数。尝试显式指定类型参数。 O:\ Ontwikkel \ TryOuts \ AnonymousTypeTest \ AnonymousTypeTest \ Form1.cs 21 25 AnonymousTypeTest   *

在我看来,TSource和TResult都是众所周知的。同时指定类型参数也是有问题的,因为我不能将 new {Value1 = x.IntValue1} 指定为类型参数。

有人知道上述解决方案的问题是什么,或者为我在此描述的挑战提供更好的解决方案?

1 个答案:

答案 0 :(得分:3)

GetList方法的定义存在问题。

public static IEnumerable<TResult> GetList<TSource, TResult>(Func<TSource, TResult> selector)

您正在添加与

中定义的TSource不同的其他类型参数TSource
 static class DataList <TSource>

您只需要从GetList定义中删除TSource。

 public static IEnumerable<TResult> GetList<TResult>(Func<TSource, TResult> selector)