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 List TableDefList { 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