我有一个我在项目中使用过的WCF。现在我想在我的其他silverlight项目中使用它。
WCF设置为根据参数给出的查询返回数据表。它不返回单一类型的数据表,因此我无法将其映射到一种类型的对象,返回的数据表的列由作为参数传递的查询定义。
现在我想在我的silverlight代码中使用相同的WCF,我知道我无法将数据表用于silverlight项目。因为我必须将此数据表转换为ienuberable / List的通用列表/ LINQ对象。
现在我正在使用以下代码进行从datatable到IEnumerable的转换>
var columns = table.Columns.Cast<DataColumn>();
return table.AsEnumerable().Select(r => columns.Select(c =>
new { Column = c.ColumnName, Value = r[c] })
.ToDictionary(i => i.Column, i => i.Value != DBNull.Value ? i.Value : null));
我希望你们这里的观点。这是进行对话的最佳方法吗?还请包括内存效率点,因为我的数据表有超过200k行。
感谢您抽出时间研究这个问题。
答案 0 :(得分:1)
在这种情况下,字典的效率非常低,因为对于每一行,您必须再次保存Name = Value对。
一个简单的优化就是为每个列存储一个值数组。
这样的事情:
from c as DataColumn in table.Columns
select new { Column=c.ColumnName, Values = table.Select(r => r[c]).ToArray() }
如果你有一个大表,我也会建议实现分页。因此,您的WCF服务方法例如具有PageSize
和PageIndex
参数。像这样你可以返回第一个,例如50行,然后是下一行,等等。
在任何情况下,您都应该考虑从服务中返回DataTable(已转换或未转换)是一个好主意。接受来自方法的查询然后返回任意结果听起来很危险。为什么不使用特定于域的方法来指定过滤器。例如GetCustomers(filter, pageIndex, pageSize)
。在过滤器对象中,您可以按名称,ID或任何需要进行过滤。然后你可以返回一个非常小的物体。
另见关于该主题的以下帖子:
http://www.hanselman.com/blog/PermaLink,guid,d88f7539-10d8-4697-8c6e-1badb08bb3f5.aspx