泛型类型上的 Linq 类型转换

Posted

技术标签:

【中文标题】泛型类型上的 Linq 类型转换【英文标题】:Linq type conversion on generic types 【发布时间】:2012-01-02 13:05:51 【问题描述】:

我找到了这段代码,但即使我尝试了多次转换,它也不起作用。基本上,它巧妙地将 Datatable 转换为可序列化的 List。

错误是它无法将Dictionary<string, object> 转换为List<object>

public GridBindingData GetSomething() 

DataTable dt = GetDatatable();

var columns = dt.Columns.Cast<System.Data.DataColumn>();

var data = dt.AsEnumerable()
    .Select(r => columns.Select(c => new  Column = c.ColumnName, Value = r[c] )
    .ToDictionary(i => i.Column, i => i.Value != System.DBNull.Value ? i.Value : null))
    .ToList<object>();

return new GridBindingData()  Data = data , Count = dt.Rows.Count ;

我尝试了许多转换,包括:

List<object> newdata = (List<object>)data.AsEnumerable().Cast<object>();

基本上,GridBindingData 的 Data 属性必须有一个List&lt;object&gt;。这可能吗?

【问题讨论】:

我猜这是 Telerik Grid。有趣的是,documentation for the GridBindingData.Data Property 没有提到它的类型(原文如此),但是 constructor does indeed take a List&lt;object&gt; 是的,它适用于 Telerik 网格,围绕客户端与 Web 服务绑定。老实说,我不想手动将每个 Datatable 写入类或动态类型。如果这作为发布 sn-p 声明的作者起作用,那将是一个完美的方式来称呼它给它一张桌子。 我没有发现问题(请参阅我更新的答案)。您遇到的错误是什么? 【参考方案1】:

嗯。很难看出你遇到了什么错误,但也许你需要.Cast&lt;object&gt;().ToList()

var data = dt.AsEnumerable()
    .Select(r => columns.Select(c => new  Column = c.ColumnName, Value = r[c] )
    .ToDictionary(i => i.Column, i => i.Value != System.DBNull.Value ? i.Value : null))
    .Cast<object>()
    .ToList();

编辑这应该可以完美运行,在 REPL 中测试:

csharp> new Dictionary<string, string>  "key","value" .ToList().Cast<object>();
 [key, value] 

csharp> new Dictionary<string, string>  "key","value" .Cast<object>().ToList();               
 [key, value] 

【讨论】:

调试后,我可以确认它确实有效。在将其标记为已回答之前,我需要了解它为什么仍然失败,请给我几分钟。 @LakiLai:会不会是因为里面的东西不能序列化? 好吧,因为我们正在转换为一个列表,它应该是可序列化的。通过使用 javascriptSerializer,我可以看到它工作正常,所以这个 Telerik 组件一定不能正确读取它。无论如何,您的代码转换得很好,问题现在存在于其他地方。感谢您和其他人的帮助。【参考方案2】:
data = dt.AsEnumerable()
    .Select(r => columns.Select(c => new  Column = c.ColumnName, Value = r[c] )
    .ToDictionary(i => i.Column, i => i.Value != System.DBNull.Value ? i.Value : null))
    .Select(x => (object)x)
    .ToList();

【讨论】:

【参考方案3】:

答案取决于您想要的结果:字典键、值,两者兼而有之?

假设您希望将值作为对象,应该这样做:

data = dt.AsEnumerable()
    .Select(r => columns.Select(c => new  Column = c.ColumnName, Value = r[c] )
    .ToDictionary(i => i.Column, i => i.Value != System.DBNull.Value ? i.Value : null))
    .Select(x => (object)x.Value)
    .ToList();

【讨论】:

以上是关于泛型类型上的 Linq 类型转换的主要内容,如果未能解决你的问题,请参考以下文章

泛型,HashMap,爆类型转换错误

为啥 Java 泛型不允许对泛型类型进行类型转换?

泛型技巧系列:如何提供类型参数之间的转换

Scala:从泛型类型到第二泛型类型的隐式转换

某些 Java 泛型类型转换中的类型安全警告是啥意思?

泛型与datatable 转化