Part 2: Describing the DataSet
The next thing I need for code generation is a reliable source of meta data describing the code I want to generate. Here I merely ask the DataSet to describe itself and store the description into a set of simplified description objects. I am moving the metadata from the DataSet into a simpler object to make it easier to deal with when I start generating code in later parts of this series.
public static DataSetDef GetDataSetDefFromDS(DataSet ds) { // Code for this class is in “The Describer Classes” section below var dsDef = new DataSetDef(ds.DataSetName, ds.Namespace); // The DataSet has a collection of DataTables foreach (var rawTable in ds.Tables) { DataTable tab = (DataTable)rawTable; // See “The Describer Classes” var tabDef = new TableDef(tab.TableName); // And each DataTable has a collection of DataColumns foreach (var rawColumn in tab.Columns) { DataColumn col = (DataColumn)rawColumn; // See “The Describer Classes” var colDef = new ColumnDef(col.ColumnName, col.DataType, col.AllowDBNull); tabDef.ColumnDefList.Add(colDef); } dsDef.TableDefList.Add(tabDef); } return dsDef; }
Getting the DataSet to Interrogate
OK, I can generate a description of the data from a DataSet, but the DataSet is in a different project. I want to make a tool that I can use
XSD Schema File
When you create a typed DataSet in Visual Studio, creates a .xsd file that it uses to generate your DataSet code. I can read the schema from an XSD file into a DataSet using the ReadXmlSchema() method:
public static DataSetDef GetDataSetDefFromXsd(string XsdPath) { DataSet ds = new DataSet(); try { ds.ReadXmlSchema(XsdPath); // Call the method above: return GetDataSetDefFromDS(ds); } catch // I don’t care what it is right now { return null; } }
In an Assembly
The DataSet may exist in a previously existing assembly; we may not even have access to the source code. Using reflection, we can activate the type and cast it as a DataSet:
public static DataSetDef doRefelctDataSetFromType(Type myObjectType) { // Create an instance of the Type: object obj = Activator.CreateInstance(myObjectType); // Try to cast it as a DataSet: DataSet ds = obj as DataSet; if (ds != null) { // Call the method above: return GetDataSetDefFromDS(ds); } return null; }
The Describer Classes
These are the classes to make the objects loaded in GetDataSetDefFromDS(). They represent a simplified description of the data. I only get the data that I think I need to generate the code later. If I later need more data, I can alter GetDataSetDefFromDS() and these classes add what I need.
public class DataSetDef { public ListTableDefList { get; private set; } public DataSetDef() { TableDefList = new List (); } public DataSetDef(string dataSetName, string nameSpace) : this() { DataSetName = dataSetName; NameSpace = nameSpace; } public string DataSetName { get; set; } public string NameSpace { get; set; } } public class TableDef { public List ColumnDefList { get; private set; } public TableDef() { ColumnDefList = new List (); } public TableDef(string tableName) : this() { TableName = tableName; } public string TableName { get; set; } } public class ColumnDef { public ColumnDef(string columnName, Type dataType, bool allowDBNull) { ColumnName = columnName; DataType = dataType; AllowDBNull = allowDBNull; } public string ColumnName { get; set; } public Type DataType { get; set; } // .NET Type, not SQL Type public bool AllowDBNull { get; set; } }
Generating a Nullable ADO.NET DataSet Wrapper: The Series
- Part 1: The Target Code
- Part 2: Describing the DataSet
- Part 3: Detour hacking parameters for T4 Templates (VS 2008)
- Part 4: The Template and putting it all together
No comments:
Post a Comment