Friday, July 3, 2009

Generate A Schema from a SQL Server Table

Xml Serialization can help if you have to save some very complex data from the web. This is the process:
  1. Post an xml document representing the business object(s) of what you want to save. This should conform to a valid schema (which I'll show you how to generate in just a second).
  2. Deserialize (unmarshall) the xml document on the server.
  3. Save the data to the database
  4. Return something (depends on your specific requirements).
So, to start with, you'll need a valid schema for the tables(s) to which you want to save data. Here's the code (in the form of a console application) to generate those schemas (unless you have some sick affinity with writing these by hand):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using System.Data;

namespace GenSchema
{
class Program
{
static void Main(string[] args)
{
string constr = @"Data Source=YOURSERVER\;Initial Catalog=YOURDB;Integrated Security=True";
string table = "yourTable";
SqlConnection conn = new SqlConnection(constr);
using (conn)
{
SqlDataAdapter sql = new SqlDataAdapter("SELECT * FROM " + table, conn);

sql.TableMappings.Add("Table", table);
DataSet ds = new DataSet("NewDataset");
sql.FillSchema(ds, SchemaType.Mapped);
ds.WriteXmlSchema(table + ".xsd");
}
}
}
}

Of course, you would fill in the information for your connection string and the table with which you want to work.

Next, to deserialize the data, you must pass in an xml document that conforms to the schema you just generated. That may require some testing, but once you get it right you're golden. If you haven't already, use the xsd.exe utility to generate the C# class from your schema. You'll notice that there are various xml attributes assigned to each property. These will be used in the deserialization process. If you already have the classes (if you're using LINQ to SQL, for example) then simply rename this new class to something else. It's only purpose is to hold the deserialized information temporarily anyway. Here's the code to deserialize your data:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using System.Data;
using System.Xml;
using System.Xml.Serialization;
using System.Text;
namespace GenSchema
{
class Program
{
static void DeSerialize(string xDoc)
{
XmlSerializer ser = new XmlSerializer(typeof(MyObject));
XmlTextReader reader = new XmlTextReader(xDoc);
MyObject obj = (MyObject)ser.Deserialize(reader);
reader.Close();
// Save using whatever method you choose.
}
}

Certainly, your situation will require some modifications to the above code, but this should at least get you started in the right direction. Hope it helps.