如何制作一个 returns 匿名类型的 IEnumerable 的方法
How to make a method that returns an IEnumerable of anonymous types
在我们的环境中,我们有很多大型业务对象。我们正在使用我们自己的数据库访问层(在此示例中简化为 'Db' class)。有时,我们想要检索业务对象中 select 部分可用属性的列表(例如,仅客户的 ID 和姓氏)。
在 Entity framework 中,我可以使用如下内容:
var keyValues = context<Customer>.Select(c => new { Id = c.ID, LastName = c.LastName, City = c.City })
但正如我之前所说,我们使用的不是 Entity FrameWork,而是我们自己的数据访问对象。对于这个例子,我创建了一个数据库对象 'Db' 和一个静态的 class 可以用来从数据库中获取数据(现在只支持一种类型的数据对象):
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' class.
public static IEnumerable<TResult> GetList<TSource, TResult>(Func<TSource, TResult> selector)
{
IEnumerable<TSource> data = Db.GetData<TSource>();
return data.Select(selector);
}
让我们忘记,在这个例子中,我会首先从数据库中获取完整的数据集,然后仅通过 select 将其中一个属性转换为匿名对象来简化数据集。
然而,问题是,上述解决方案不起作用。我在下面的行中收到编译器错误:
var items = DataList<DataClass>.GetList(x => new { Value1 = x.IntValue1 });
错误是:
*Error 2 The type arguments for method 'AnonymousTypeTest.DataList.GetList(System.Func)' cannot be inferred from the usage. Try specifying the type arguments explicitly. O:\Ontwikkel\TryOuts\AnonymousTypeTest\AnonymousTypeTest\Form1.cs 21 25 AnonymousTypeTest
*
在我看来,TSource 和TResult 都是已知的。指定类型参数也是有问题的,因为我无法指定 new { Value1 = x.IntValue1 } 作为类型参数。
有人知道上述解决方案的问题是什么,或者有更好的解决方案来应对我在这里描述的挑战吗?
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)
在我们的环境中,我们有很多大型业务对象。我们正在使用我们自己的数据库访问层(在此示例中简化为 'Db' class)。有时,我们想要检索业务对象中 select 部分可用属性的列表(例如,仅客户的 ID 和姓氏)。
在 Entity framework 中,我可以使用如下内容:
var keyValues = context<Customer>.Select(c => new { Id = c.ID, LastName = c.LastName, City = c.City })
但正如我之前所说,我们使用的不是 Entity FrameWork,而是我们自己的数据访问对象。对于这个例子,我创建了一个数据库对象 'Db' 和一个静态的 class 可以用来从数据库中获取数据(现在只支持一种类型的数据对象):
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' class.
public static IEnumerable<TResult> GetList<TSource, TResult>(Func<TSource, TResult> selector)
{
IEnumerable<TSource> data = Db.GetData<TSource>();
return data.Select(selector);
}
让我们忘记,在这个例子中,我会首先从数据库中获取完整的数据集,然后仅通过 select 将其中一个属性转换为匿名对象来简化数据集。
然而,问题是,上述解决方案不起作用。我在下面的行中收到编译器错误:
var items = DataList<DataClass>.GetList(x => new { Value1 = x.IntValue1 });
错误是:
*Error 2 The type arguments for method 'AnonymousTypeTest.DataList.GetList(System.Func)' cannot be inferred from the usage. Try specifying the type arguments explicitly. O:\Ontwikkel\TryOuts\AnonymousTypeTest\AnonymousTypeTest\Form1.cs 21 25 AnonymousTypeTest *
在我看来,TSource 和TResult 都是已知的。指定类型参数也是有问题的,因为我无法指定 new { Value1 = x.IntValue1 } 作为类型参数。
有人知道上述解决方案的问题是什么,或者有更好的解决方案来应对我在这里描述的挑战吗?
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)