<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>invalid operation - Linq To Schema</title>
    <link>http://blog.invalidoperation.com/</link>
    <description>how do i wrote codes</description>
    <language>en-us</language>
    <copyright>ray</copyright>
    <lastBuildDate>Sun, 12 Apr 2009 01:55:36 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.2.8279.16125</generator>
    <managingEditor>ray.oneill@gmail.com</managingEditor>
    <webMaster>ray.oneill@gmail.com</webMaster>
    <item>
      <trackback:ping>http://blog.invalidoperation.com/Trackback.aspx?guid=e438521a-dadc-4722-b54c-6756f3d3db43</trackback:ping>
      <pingback:server>http://blog.invalidoperation.com/pingback.aspx</pingback:server>
      <pingback:target>http://blog.invalidoperation.com/PermaLink,guid,e438521a-dadc-4722-b54c-6756f3d3db43.aspx</pingback:target>
      <dc:creator>Ray</dc:creator>
      <wfw:comment>http://blog.invalidoperation.com/CommentView,guid,e438521a-dadc-4722-b54c-6756f3d3db43.aspx</wfw:comment>
      <wfw:commentRss>http://blog.invalidoperation.com/SyndicationService.asmx/GetEntryCommentsRss?guid=e438521a-dadc-4722-b54c-6756f3d3db43</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
 
</p>
        <p>
          <a href="http://blog.invalidoperation.com/2009/02/16/DatabaseMetadataInNetPart1TheProblem.aspx">Getting
at your database metadata is a pain in the ass</a>. In my casual development of NDeavor,
I’m also writing some providers for various database platforms, currently focused
around MySql because it has good .NET support and it’s not Sql Server, which I actually
work with every day (in the professional sense).  It became clear pretty quickly
that without a fully-featured API like SMO that using the functionality in .GetSchema()
off of an ADO.NET-compliant vendor’s connection class is the best bet all around.
</p>
        <p>
Being that I want a solution I can use for all the providers I end up doing for NDeavor,
and be as lightweight as possible, <a href="http://www.hanselman.com/blog/T4TextTemplateTransformationToolkitCodeGenerationBestKeptVisualStudioSecret.aspx">T4
templates</a> was the best choice. Oh, and I want it LINQ-enabled as well. It will
basically do the following: 
<br />
- Call .GetSchema() on a DbConnection instance to get available metadata (as well
as specific collections you tell it to). 
<br />
- Ouput a C# POCO class with properties mapping to each column of the metadata’s DataTable
that GetSchema() returns 
<br />
- Output a DataContext-like class allowing for LINQ goodness.
</p>
        <p>
You might think:
</p>
        <blockquote>
          <p>
            <em>“Really? You’re getting the schema of a DataTable returned from </em>
            <em>DbConnection.GetSchema()
so it can used to create the schema for a C# class which will be used to query the
schema of a relational database?”</em>
          </p>
        </blockquote>
        <p>
and you’d be right. So?
</p>
        <p>
The idea of DBConnection.GetSchema(), in Microsoft terms, was to allow querying of
vendor-specific metadata about the underlying data source, so as a lowest-common-denominator
it returns instances of the ubiquitous DataTable and DataSet. Passing around loosely
typed blobs of data won’t cut it, so we’ll be mapping these to strongly types classes,
similar to that of an ORM framework. That sounds tedious and like a job for some lightweight
code generation, in this case it will be some T4 template magic in Visual Studio 2008.
These classes will just be thin wrappers over DataRows, they won’t have the associations/relationship
semantics you’re used to seeing with Linq to Sql or Entity Framework, they’re just
glue to support building up a larger more api-friendly object model. Any of the joins
you do from the resulting object collections will be in-memory, there’s nothing dynamically
querying the underlying schema. It’s all smoke and mirrors.
</p>
        <h4>5 Steps to LINQ-ifying to your Db Schema
</h4>
        <p>
          <a href="/downloads/LinqToSchema_04112009.zip">Download LinqToSchema</a>
        </p>
        <ol>
          <li>
Add LinqToSchema.tt to your Visual Studio 2008 project, and remove the ‘Custom Tool’
setting – this is not the template itself, just for inclusion inside the ‘host’ template. 
</li>
          <li>
Create a new T4 template by adding a text file to your project and renaming the extension
to .tt 
</li>
          <li>
Write the template to look similar to this: <pre class="c#" name="code">&lt;#@ template language="C#v3.5" hostspecific="True" debug="true" #&gt;
&lt;#@ output extension="cs" #&gt;
&lt;#@ include file="LinqToSchema.tt" #&gt;
&lt;# 
    LinqToSchemaSettings settings = new LinqToSchemaSettings
    {
        ConnectionStringName = "Chinook_MySql",    // name of connection string in local App.Config/Web.Config - must be in same dir as this file
        TargetNamespace = "Chinook.Schema.MySql",    // what namespace to put the generated code in
        ClassNamePrefix = "MySql",                        // what prefix, if any, to put on the generated class names
        ClassVisibility = Visibility.Public                // visibility of the generated classes (Public or Internal)
    };
   
    LinqToSchemaClassesGenerator generator = new LinqToSchemaClassesGenerator(settings);
    generator.Run();
#&gt;</pre></li>
          <li>
Save your just-created template for it to be processed by the T4 engine. 
</li>
          <li>
Compile/write other code that uses the generated classes. Such as: 
<br /><pre class="c#" name="code">using (MySqlSchemaContext ctx = new MySqlSchemaContext(@"server=servername;user id=userid;persist security info=True;database=chinook"))
{
    var query = from tbl in ctx.Tables
                join col in ctx.Columns on tbl.TableName equals col.TableName
                where tbl.TableName.ToLower() == "track"
                select new
                {
                    tbl.TableCatalog,
                    tbl.TableName,
                    col.ColumnName,
                    col.DataType,
                    col.IsNullable
                };
    query.ToList().ForEach(p =&gt; Console.WriteLine(p));
}</pre></li>
        </ol>
        <p>
There are some more options such as explicitly setting the connection string, which
are explained in the readme. And if it wasn’t already clear, because this is using
DbConnection.GetSchema(), it’s usable on any database platform that returns meaningful
metadata using from their platform-specific DbConnection implementation.
</p>
        <img width="0" height="0" src="http://blog.invalidoperation.com/aggbug.ashx?id=e438521a-dadc-4722-b54c-6756f3d3db43" />
      </body>
      <title>Database Metadata in .Net Part 2 : LINQ To Schema</title>
      <guid isPermaLink="false">http://blog.invalidoperation.com/PermaLink,guid,e438521a-dadc-4722-b54c-6756f3d3db43.aspx</guid>
      <link>http://blog.invalidoperation.com/2009/04/12/DatabaseMetadataInNetPart2LINQToSchema.aspx</link>
      <pubDate>Sun, 12 Apr 2009 01:55:36 GMT</pubDate>
      <description>&lt;p&gt;
&amp;#160;
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.invalidoperation.com/2009/02/16/DatabaseMetadataInNetPart1TheProblem.aspx"&gt;Getting
at your database metadata is a pain in the ass&lt;/a&gt;. In my casual development of NDeavor,
I’m also writing some providers for various database platforms, currently focused
around MySql because it has good .NET support and it’s not Sql Server, which I actually
work with every day (in the professional sense).&amp;#160; It became clear pretty quickly
that without a fully-featured API like SMO that using the functionality in .GetSchema()
off of an ADO.NET-compliant vendor’s connection class is the best bet all around.
&lt;/p&gt;
&lt;p&gt;
Being that I want a solution I can use for all the providers I end up doing for NDeavor,
and be as lightweight as possible, &lt;a href="http://www.hanselman.com/blog/T4TextTemplateTransformationToolkitCodeGenerationBestKeptVisualStudioSecret.aspx"&gt;T4
templates&lt;/a&gt; was the best choice. Oh, and I want it LINQ-enabled as well. It will
basically do the following: 
&lt;br /&gt;
- Call .GetSchema() on a DbConnection instance to get available metadata (as well
as specific collections you tell it to). 
&lt;br /&gt;
- Ouput a C# POCO class with properties mapping to each column of the metadata’s DataTable
that GetSchema() returns 
&lt;br /&gt;
- Output a DataContext-like class allowing for LINQ goodness.
&lt;/p&gt;
&lt;p&gt;
You might think:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
&lt;em&gt;“Really? You’re getting the schema of a DataTable returned from &lt;/em&gt;&lt;em&gt;DbConnection.GetSchema()
so it can used to create the schema for a C# class which will be used to query the
schema of a relational database?”&lt;/em&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
and you’d be right. So?
&lt;/p&gt;
&lt;p&gt;
The idea of DBConnection.GetSchema(), in Microsoft terms, was to allow querying of
vendor-specific metadata about the underlying data source, so as a lowest-common-denominator
it returns instances of the ubiquitous DataTable and DataSet. Passing around loosely
typed blobs of data won’t cut it, so we’ll be mapping these to strongly types classes,
similar to that of an ORM framework. That sounds tedious and like a job for some lightweight
code generation, in this case it will be some T4 template magic in Visual Studio 2008.
These classes will just be thin wrappers over DataRows, they won’t have the associations/relationship
semantics you’re used to seeing with Linq to Sql or Entity Framework, they’re just
glue to support building up a larger more api-friendly object model. Any of the joins
you do from the resulting object collections will be in-memory, there’s nothing dynamically
querying the underlying schema. It’s all smoke and mirrors.
&lt;/p&gt;
&lt;h4&gt;5 Steps to LINQ-ifying to your Db Schema
&lt;/h4&gt;
&lt;p&gt;
&lt;a href="/downloads/LinqToSchema_04112009.zip"&gt;Download LinqToSchema&lt;/a&gt;
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Add LinqToSchema.tt to your Visual Studio 2008 project, and remove the ‘Custom Tool’
setting – this is not the template itself, just for inclusion inside the ‘host’ template. 
&lt;/li&gt;
&lt;li&gt;
Create a new T4 template by adding a text file to your project and renaming the extension
to .tt 
&lt;/li&gt;
&lt;li&gt;
Write the template to look similar to this: &lt;pre class="c#" name="code"&gt;&amp;lt;#@ template language=&amp;quot;C#v3.5&amp;quot; hostspecific=&amp;quot;True&amp;quot; debug=&amp;quot;true&amp;quot; #&amp;gt;
&amp;lt;#@ output extension=&amp;quot;cs&amp;quot; #&amp;gt;
&amp;lt;#@ include file=&amp;quot;LinqToSchema.tt&amp;quot; #&amp;gt;
&amp;lt;# 
    LinqToSchemaSettings settings = new LinqToSchemaSettings
    {
        ConnectionStringName = &amp;quot;Chinook_MySql&amp;quot;,    // name of connection string in local App.Config/Web.Config - must be in same dir as this file
        TargetNamespace = &amp;quot;Chinook.Schema.MySql&amp;quot;,    // what namespace to put the generated code in
        ClassNamePrefix = &amp;quot;MySql&amp;quot;,                        // what prefix, if any, to put on the generated class names
        ClassVisibility = Visibility.Public                // visibility of the generated classes (Public or Internal)
    };
   
    LinqToSchemaClassesGenerator generator = new LinqToSchemaClassesGenerator(settings);
    generator.Run();
#&amp;gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
Save your just-created template for it to be processed by the T4 engine. 
&lt;/li&gt;
&lt;li&gt;
Compile/write other code that uses the generated classes. Such as: 
&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;using (MySqlSchemaContext ctx = new MySqlSchemaContext(@&amp;quot;server=servername;user id=userid;persist security info=True;database=chinook&amp;quot;))
{
    var query = from tbl in ctx.Tables
                join col in ctx.Columns on tbl.TableName equals col.TableName
                where tbl.TableName.ToLower() == &amp;quot;track&amp;quot;
                select new
                {
                    tbl.TableCatalog,
                    tbl.TableName,
                    col.ColumnName,
                    col.DataType,
                    col.IsNullable
                };
    query.ToList().ForEach(p =&amp;gt; Console.WriteLine(p));
}&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
There are some more options such as explicitly setting the connection string, which
are explained in the readme. And if it wasn’t already clear, because this is using
DbConnection.GetSchema(), it’s usable on any database platform that returns meaningful
metadata using from their platform-specific DbConnection implementation.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.invalidoperation.com/aggbug.ashx?id=e438521a-dadc-4722-b54c-6756f3d3db43" /&gt;</description>
      <comments>http://blog.invalidoperation.com/CommentView,guid,e438521a-dadc-4722-b54c-6756f3d3db43.aspx</comments>
      <category>database</category>
      <category>Linq To Schema</category>
      <category>meta</category>
      <category>metadata</category>
      <category>NDeavor</category>
    </item>
  </channel>
</rss>