Typed Dataset not using TypedTableBase in .NET 4
I'm migrating our DAL class library to .NET 4 (from .NET 3.5). We're using typed datasets quite often, and we often iterate over tables:
foreach(var row in ds.MyTable) var tmp = row.ID;
This does not work anymore, as the designer changes the dataset's code so that tables do not derive from TypedTableBase<T>
anymore, but from DataTable
(and implement the non-generic IEnumerable
). That's what the diff shows. Therefore, the row is of type object
开发者_StackOverflow社区 at compile-time.
Does anybody know if this is the usual behavior? At the moment, I'm doing it the way shown below, but I hope there's a more elegant solution:
foreach(var row in ds.MyTable.Cast<MyDs.MyRow>()) var tmp = row.ID;
Just ran into this today and was able to correct it by doing the following:
Select the xsd files in the solution explorer and click "Run Custom Tool". The designer files will be regenerated using TypedTableBase instead of DataTable and IEnumerable.
The accepted answer is mostly complete, but will not fully resolve the issue.
Here's a reproduction of my question and answer on this issue.
The Problem:
In short, the problem occurs when the MSDataSetGenerator
tool runs, but the System.Data.DataSetExtensions
assembly has not yet been loaded into the current Visual Studio process.
The Solution:
One way to load the assembly is just to open any XSD file and THEN re-generate the designer code.
The following steps should generate the appropriate designer file:
- Open any XSD file to the designer view (this loads DataSetExtensions.dll)
- Right Click on the XSD and Select
Run Custom Tool
Here's a full step by step walkthrough of the issue and solution with pictures
Other Instances:
This problem has also been reported to Microsoft in the following bug tickets:
- #668724 - MSDataSetGenerator generates incorrect output sometimes
- #733077 - MSDataSetGenerator does not generate TypedTableBase derived classes
All this is correct but in my case I had to support source code which needs to run with .Net 2.0 and .Net 4.0. My objective was to change as little code as possible.
My solution was to create a partial extension under .Net 4.0 and bind it to the 4.0 application. This looks like:
namespace NamespaceOfMyDataSet
{
public partial class MyDataSet : global::System.Data.DataSet
{
public partial class MyTypedTable : global::System.Data.TypedTableBase<MyTypedTableRow>
{
public System.Data.DataRowCollection GetRows()
{
return this.Rows;
}
}
}
}
This works like a charme!!!
精彩评论