Friday, March 09, 2007

LINQ's Missing ToDataTable Method Saga

Several LINQ pilgrims, including Julie Lerman, the authors of three books about LINQ (two published and one in process), Mike Taulty and I, have been attempting to find the IEnumerable<T>.ToDataTable and DataTable.LoadSequence methods in the Orcas March 2007 CTP's LINQ implementation.

Here's the answer from ADO.NET program manager Erick Thompson, author of the LINQ to DataSet documentation series, in the LINQ Project General Forum:

We decided to remove the ToDataTable for any sequence, as there isn't a correct way to always load data from a sequence into a DataTable. For example, what do you do with a sequence of Type A where some instances are also Type B, where B inherits from A? Do you extend the DataTable schema to allow for the additional fields in B? Throw an error? Not load the additional data?

We are looking at bringing this functionality back at some point. What would be helpful is a better understanding of what you would like to use it for. What LINQ to XXX queries do you want to load into a DataTable, and why?

My immediate reaction was that there would be few, if any, System.Data namespace members were such "always" restrictions applied to them.

Fabrice Marguerie's reply makes the most sense to me:

I would expect the behavior to be basic. I think that most of the time when we work with DataSets, we do not use mixed data types. Often the data will come from LINQ to SQL or LINQ to XML queries that return only of type of data as specified in their select clause.

I would bring back the ToDataTable and LoadSequence operators back to life, even if they throw exceptions in unsupported cases. These cases would be the minority, I think. Of these cases should be documented. It probably require more thought, but having ToDataTable use only the members of the base type (the generic type T of the sequence) can be an acceptable limitation, I think.

One issue is that operating on a non-homogeneous type would appear to throw runtime not compile-time, exceptions. A major objective of LINQ is to substitute compile-time for runtime exceptions.

Update 4/4/2007: Julie Lerman points to Fabio Claudio Ferracchiati's May 2006 to March 2007 comparison list post of March 7, 2007, that lists the differences between the two CTPs' LINQ implementation. Fabio is the author of LINQ for Visual C# 2005 and LINQ for VB 2005 books mentioned the first paragraph of this post. Fabio also has posted updated code for the C# title. You can buy either title as a downloadable eBook from Apress.

4 comments:

Rory said...

Aren't the scenarios listed by Mr. Thompson already well-modeled by the DataSet.Merge algorithm and associated MissingSchemaAction enum?

Seems to me that putting this tool into developers hands would be a great way to keep the simple case simple, and subject us to the same level of run-time error protection we currently enjoy - specifically typed exceptions. If I'm using a simpler domain logic pattern, involving DataSet, this is just what I need. If I am using a more sophisticated domain logic pattern, like Domain Model, I won't use the ToDataTable method, just as I don't use the DataSet. As typing is more important in this higher level of complexity, I'll use, and be thankful for, compile-time verification of LINQ expressions and types, leaving ToDataTable out of the equation.

Fabrice Marguerie said...

Rory, you forget that a common use case is interacting with legacy code or tools that expect DataSet to work.
Reporting tools often use DataSets as input for example. Another benefit of DataSets is that they can easily be persisted in XML or binary formats, a service that is not provided by LINQ.
This means that converting the results of a LINQ to XXX query into a DataSet can be useful.

Anonymous said...

qcsglll
车库门
卷帘门
伸缩门
翻译公司
道闸
挡车器
伸缩门
货架
货架
货架
货架
货架
电动伸缩门
车库门
自动车库门
防火卷帘门
阳光房
除湿机
抽湿机
比歘情



电动伸缩门
伸缩门
卷帘门
车库门
道闸
挡车器
岗亭
道闸
伸缩门
自动门
车库门
岗亭
日上
日上防盗门
电动伸缩门
卷帘门
伸缩门


自动车库门
车库门
伸缩门
自动门
电动门
伸缩门
卷帘门
车库门
电动伸缩门
道闸
岗亭
自动车库门
电动伸缩门
岗亭
卷帘门
车库门
伸缩门
电动门
自动门



卷帘门
电动门
自动门
卷帘门
道闸
车库门
伸缩门
岗亭
岗亭
岗亭
岗亭
岗亭
岗亭
车库门
道闸
卷帘门
防火卷帘门
电动伸缩门
道闸


防火卷帘门
自动车库门
车库门
伸缩门
电动伸缩门
挡车器
北京SEO
专业SEO
专业SEO
专业SEO
锅炉安装
Oracle数据库容灾复制
Oracle容灾备份
Oracle备份恢复
北京铁艺





bgwldwzjzzxh!!
妇科
六合彩
热门图库
热门图库精

Unknown said...

've written a small library myself to accomplish this task. It uses reflection only for the first time an object type is to be translated to a datatable. It emits a method that will do all the work translating an object type.

Its blazing fast. You can find it here: ModelShredder on GoogleCode