Converting a LINQ to Entities query to a DataTable
2008-10-15 23:11
387 查看
[Update at bottom of post]
I wrote this in response to a question on the ADO.NET Orcas forums and thought I would copy it here.
Note that Danny Simmons writes more information about Entity Framework and DataTables in the thread.
Here's my solution for now...
LINQ to Datasets does allow for conversions from queries to Datatables, but it doesn't seem to be able to deal with ObjectQueries. I then queried my objectquery to return an IQueryable and also an IEnumerable, but I couldn't get the datatable conversion to work. Look for CopyToDataTable in the VS2008 documentation for more info on that.
So since I couldn't get at it I rolled my own using Mike Taulty's previous example (not for ObjectQueries though) as a start.
This example uses the ObjectStateManager so I can dynamically get at the values. As long as I'm already using the ObjetStateManager, I also use it to get some metadata, even though I could have used the MetadataWorkspace for that.
Assuming we are starting with nwrows which is an ObjectQuery for a simple Linq to Entities query...
Dim dt As New DataTable
Dim currow As Integer = 0 'just a counter to keep track of my for each position
For Each r In nwrows
'get statemanager for current row
Dim stateEntry = nwts.ObjectStateManager.GetObjectStateEntry(CType(r, Data.Objects.DataClasses.IEntityWithKey).EntityKey)
'this will only happen once, build the dataColumns, I'm not bothering with their names
If dt.Columns.Count = 0 Then
For i = 0 To stateEntry.CurrentValues.FieldCount - 1
dt.Columns.Add()
Next
End If
'now we can add data, grabbing current values
Dim dtrow As DataRow = dt.NewRow
For idata = 0 To stateEntry.CurrentValues.FieldCount - 1
dtrow.Item(idata) = stateEntry.CurrentValues(idata)
Next
dt.Rows.Add(dtrow)
currow += 1
Next
[Update]
Note: It looks like Andrew Conrad, who is on the ADO.NET team, also got inspired today by the forum question as he has written a much more indepth (read "not quite the hack that I wrote") solution to the loss of the datatable conversion capability. In fact he explains why we can't use it with non-Linq to Dataset queries:
In the original Linq CTP and the first Orcas Beta, we included a DataSet specific Linq operator called CopyToDataTable<T> (It was called ToDataTable at one point also). For Beta 2 of Orcas, we ended up restricting this method to only work with DataRows (or some derived type) via a generic constraint on the method.
So, like a good soldier, he wrote up some sweet code to do the job. I was only pulling in the values. He's got tablenames and types and subtypes as well, with a completely different approach. Definitely check it out. I will probably just use this rather than my hack and try to consider my experimenting with StateObject a good use of my time yesterday!
I wrote this in response to a question on the ADO.NET Orcas forums and thought I would copy it here.
Note that Danny Simmons writes more information about Entity Framework and DataTables in the thread.
Here's my solution for now...
LINQ to Datasets does allow for conversions from queries to Datatables, but it doesn't seem to be able to deal with ObjectQueries. I then queried my objectquery to return an IQueryable and also an IEnumerable, but I couldn't get the datatable conversion to work. Look for CopyToDataTable in the VS2008 documentation for more info on that.
So since I couldn't get at it I rolled my own using Mike Taulty's previous example (not for ObjectQueries though) as a start.
This example uses the ObjectStateManager so I can dynamically get at the values. As long as I'm already using the ObjetStateManager, I also use it to get some metadata, even though I could have used the MetadataWorkspace for that.
Assuming we are starting with nwrows which is an ObjectQuery for a simple Linq to Entities query...
Dim dt As New DataTable
Dim currow As Integer = 0 'just a counter to keep track of my for each position
For Each r In nwrows
'get statemanager for current row
Dim stateEntry = nwts.ObjectStateManager.GetObjectStateEntry(CType(r, Data.Objects.DataClasses.IEntityWithKey).EntityKey)
'this will only happen once, build the dataColumns, I'm not bothering with their names
If dt.Columns.Count = 0 Then
For i = 0 To stateEntry.CurrentValues.FieldCount - 1
dt.Columns.Add()
Next
End If
'now we can add data, grabbing current values
Dim dtrow As DataRow = dt.NewRow
For idata = 0 To stateEntry.CurrentValues.FieldCount - 1
dtrow.Item(idata) = stateEntry.CurrentValues(idata)
Next
dt.Rows.Add(dtrow)
currow += 1
Next
[Update]
Note: It looks like Andrew Conrad, who is on the ADO.NET team, also got inspired today by the forum question as he has written a much more indepth (read "not quite the hack that I wrote") solution to the loss of the datatable conversion capability. In fact he explains why we can't use it with non-Linq to Dataset queries:
In the original Linq CTP and the first Orcas Beta, we included a DataSet specific Linq operator called CopyToDataTable<T> (It was called ToDataTable at one point also). For Beta 2 of Orcas, we ended up restricting this method to only work with DataRows (or some derived type) via a generic constraint on the method.
So, like a good soldier, he wrote up some sweet code to do the job. I was only pulling in the values. He's got tablenames and types and subtypes as well, with a completely different approach. Definitely check it out. I will probably just use this rather than my hack and try to consider my experimenting with StateObject a good use of my time yesterday!
相关文章推荐
- How do I write a LINQ to Entities query which has the equivalent of the SQL “in” keyword?
- Working with LINQ to Entities & LINQ to DataTable
- Linq to Entity 中 , Query不应该有耗时操作
- 【项目实战】--仅对 LINQ to Entities 中已排序的输入支持方法“Skip”。必须在调用“Skip”方法之前调用方法“OrderBy”
- LINQ to Entities
- Linq中字段数据类型转换问题(Linq to entity,LINQ to Entities 不识别方法"System.String ToString()"问题解决)
- LINQ To DataTable
- Linq to Sql 或linq to entities 与SQL 查询结果不一致,返回重复结果问题解决方法
- 再接再厉VS 2008 sp1 + .NET 3.5 sp1(2) - Entity Framework(实体框架)之详解 Linq To Entities 之一
- 再接再厉VS 2008 sp1 + .NET 3.5 sp1(3) - Entity Framework(实体框架)之详解 Linq To Entities 之二
- Entity Framework 4 in Action读书笔记——第四章:使用LINQ to Entities查询:使用函数
- LINQ to Entities does not recognize the method ToString()
- LINQ to Entities/实体综合语言查询
- 【福分系统】 LINQ to Entities 不识别方法“System.DateTime ToDateTime(System.String)”,因此该方法无法转换为存储表达式。
- LINQ to Entities
- linq to datatable 和lambda查询datatable
- Linq to Entities in Ado.net EF的事务
- LinqToEntities:Union IEqualityComparer
- LINQ to Entities 实现sql 关键字"In"方式总结
- Comparison of user class objects is not supported in Linq to entities