<?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</title>
    <link>http://blog.invalidoperation.com/</link>
    <description>how do i wrote codes</description>
    <language>en-us</language>
    <copyright>ray</copyright>
    <lastBuildDate>Sun, 14 Mar 2010 21:30:00 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=1acef3c4-1afa-49d6-9a16-5ff162726c9d</trackback:ping>
      <pingback:server>http://blog.invalidoperation.com/pingback.aspx</pingback:server>
      <pingback:target>http://blog.invalidoperation.com/PermaLink,guid,1acef3c4-1afa-49d6-9a16-5ff162726c9d.aspx</pingback:target>
      <dc:creator>Ray</dc:creator>
      <wfw:comment>http://blog.invalidoperation.com/CommentView,guid,1acef3c4-1afa-49d6-9a16-5ff162726c9d.aspx</wfw:comment>
      <wfw:commentRss>http://blog.invalidoperation.com/SyndicationService.asmx/GetEntryCommentsRss?guid=1acef3c4-1afa-49d6-9a16-5ff162726c9d</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I’ve had Bill Reiss’ <a href="http://blogs.silverarcade.com/silverlight-games-101">Silverlight
Games 101</a> blog in my Google reader for a while now, and recently he’s started
a new series started on developing the Asteroids-like “Space Rocks” game under Silverlight
3. Between <a href="http://blogs.silverarcade.com/silverlight-games-101/09/silverlight-space-rocks-game-step-3-sprites-part-2/">part
3</a> and <a href="http://blogs.silverarcade.com/silverlight-games-101/14/silverlight-space-rocks-game-step-4-inheriting-from-sprite/">part
4</a> was a post promoting <a href="http://blogs.silverarcade.com/silverlight-games-101/12/silverlight-setting-dependency-properties-and-the-effect-on-performance/">caching
dependency property values for performance</a>. I’m not a WPF or Silverlight guru
so I can’t really argue with the statement; but it does make sense in the same way
that caching static data in a line of business application does. 
</p>
        <p>
In <a href="http://blogs.silverarcade.com/silverlight-games-101/14/silverlight-space-rocks-game-step-4-inheriting-from-sprite/">part
4</a> we see this in action, in properties on the <em>Sprite</em> class:
</p>
        <pre class="c#" name="code">        public double X
        {
            get
            {
                return x;
            }
            set
            {
                if (x != value)
                {
                    x = value;
                    this.SetValue(Canvas.LeftProperty, x - dw);
                }
            }
        }

        public double Y
        {
            get
            {
                return y;
            }
            set
            {
                if (y != value)
                {
                    y = value;
                   this.SetValue(Canvas.TopProperty, y - dh);
                }
            }
        }</pre>
        <p>
I don’t like the duplication of the caching inside of the class itself, especially
when dependency properties are likely to be used quite heavily in a game, which is
going to be doing things like adjusting position of visual game elements every rendered
frame. Surely, this is unnecessary duplication and we can do better? Behold, the DependencyPropertyCache:
</p>
        <pre class="c#" name="code">using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace SpaceRocks
{
    public class DependencyPropertyCache&lt;T&gt;
    {
        private DependencyProperty _dependencyProperty;
        private DependencyObject _parent;

        public DependencyPropertyCache(DependencyObject parent, DependencyProperty property)
        {
            if (parent == null)
                throw new ArgumentNullException("parent");
            if (property == null)
                throw new ArgumentNullException("property");

            _parent = parent;
            _dependencyProperty = property;
        }

        public T Value { get; private set; }

        public void SetValue(T value)
        {
            if (!Value.Equals(value))
            {
                _parent.SetValue(_dependencyProperty, value);
                this.Value = value;
            }
        }
    }
}</pre>
        <p>
Pretty simple, really. Now we can have cached values exposed by the <em>Value </em>property
and update the value using <em>SetValue </em>which does a comparison between old and
new, and only updates the actual dependency property if the new value is different.
Bill was using the inequality operator and this class is using the <em>Equals </em>method
on System.Object, however it wouldn’t be very difficult to modify the cache to constrain
T to implementing IComparable&lt;T&gt;, as System.Double does, and/or a constructor
overload which might take a custom IComparable&lt;T&gt;. So far in the series, there
are only System.Double properties, so I’ve not done that yet.
</p>
        <p>
So now the modified code for the <em>Sprite </em>class from <a href="http://blogs.silverarcade.com/silverlight-games-101/14/silverlight-space-rocks-game-step-4-inheriting-from-sprite/">part
4</a> looks like this:  
</p>
        <pre class="c#" name="code">using System.Windows.Controls;
using Microsoft.Xna.Framework;
using System.Windows;
using System.Windows.Media;

namespace SpaceRocks
{
    public class Sprite : Control
    {
        double dw = 0;
        double dh = 0; 
        static Vector2 gameSize = new Vector2(640, 480);
        private DependencyPropertyCache&lt;double&gt; _x;
        private DependencyPropertyCache&lt;double&gt; _y;
 
        public Sprite()
        {
            this.DefaultStyleKey = typeof(Sprite);
            this.SizeChanged += new SizeChangedEventHandler(Sprite_SizeChanged);
            _x = new DependencyPropertyCache&lt;double&gt;(this, Canvas.LeftProperty);
            _y = new DependencyPropertyCache&lt;double&gt;(this, Canvas.TopProperty);
        }

        void Sprite_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            Vector2 pos = Position;           
            
            _x.SetValue(double.NaN);
            _y.SetValue(double.NaN);

            Position = pos;
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            FrameworkElement element = VisualTreeHelper.GetChild(this, 0) as FrameworkElement;
            dw = element.Width / 2;
            dh = element.Height / 2;
            Width = element.Width;
            Height = element.Height;
        }

        public double X
        {
            get
            {
                return _x.Value;
            }
            set
            {
                _x.SetValue(value - dw);                
            }
        }

        public double Y
        {
            get
            {
                return _y.Value;
            }
            set
            {
                _y.SetValue(value - dh);                
            }
        }

        public Vector2 Position
        {
            get
            {
                return new Vector2( (float)_x.Value, (float)_y.Value);
            }
            set
            {
                _x.SetValue(value.X);
                _y.SetValue(value.Y);
            }
        }

        public Vector2 Velocity { get; set; }

        public void Update(double elapsedSeconds)
        {
            Position += Velocity * (float)elapsedSeconds;
            if (Position.X &gt; gameSize.X) Position -= new Vector2(gameSize.X, 0);
            if (Position.X &lt; 0) Position += new Vector2(gameSize.X, 0);
            if (Position.Y &gt; gameSize.Y) Position -= new Vector2(0, gameSize.Y);
            if (Position.Y &lt; 0) Position += new Vector2(0, gameSize.Y);
        }
    }
}</pre>
        <p>
Sweet.
</p>
        <img width="0" height="0" src="http://blog.invalidoperation.com/aggbug.ashx?id=1acef3c4-1afa-49d6-9a16-5ff162726c9d" />
      </body>
      <title>Caching Silverlight Dependency Properties</title>
      <guid isPermaLink="false">http://blog.invalidoperation.com/PermaLink,guid,1acef3c4-1afa-49d6-9a16-5ff162726c9d.aspx</guid>
      <link>http://blog.invalidoperation.com/2010/03/14/CachingSilverlightDependencyProperties.aspx</link>
      <pubDate>Sun, 14 Mar 2010 21:30:00 GMT</pubDate>
      <description>&lt;p&gt;
I’ve had Bill Reiss’ &lt;a href="http://blogs.silverarcade.com/silverlight-games-101"&gt;Silverlight
Games 101&lt;/a&gt; blog in my Google reader for a while now, and recently he’s started
a new series started on developing the Asteroids-like “Space Rocks” game under Silverlight
3. Between &lt;a href="http://blogs.silverarcade.com/silverlight-games-101/09/silverlight-space-rocks-game-step-3-sprites-part-2/"&gt;part
3&lt;/a&gt; and &lt;a href="http://blogs.silverarcade.com/silverlight-games-101/14/silverlight-space-rocks-game-step-4-inheriting-from-sprite/"&gt;part
4&lt;/a&gt; was a post promoting &lt;a href="http://blogs.silverarcade.com/silverlight-games-101/12/silverlight-setting-dependency-properties-and-the-effect-on-performance/"&gt;caching
dependency property values for performance&lt;/a&gt;. I’m not a WPF or Silverlight guru
so I can’t really argue with the statement; but it does make sense in the same way
that caching static data in a line of business application does. 
&lt;/p&gt;
&lt;p&gt;
In &lt;a href="http://blogs.silverarcade.com/silverlight-games-101/14/silverlight-space-rocks-game-step-4-inheriting-from-sprite/"&gt;part
4&lt;/a&gt; we see this in action, in properties on the &lt;em&gt;Sprite&lt;/em&gt; class:
&lt;/p&gt;
&lt;pre class="c#" name="code"&gt;        public double X
        {
            get
            {
                return x;
            }
            set
            {
                if (x != value)
                {
                    x = value;
                    this.SetValue(Canvas.LeftProperty, x - dw);
                }
            }
        }

        public double Y
        {
            get
            {
                return y;
            }
            set
            {
                if (y != value)
                {
                    y = value;
                   this.SetValue(Canvas.TopProperty, y - dh);
                }
            }
        }&lt;/pre&gt;
&lt;p&gt;
I don’t like the duplication of the caching inside of the class itself, especially
when dependency properties are likely to be used quite heavily in a game, which is
going to be doing things like adjusting position of visual game elements every rendered
frame. Surely, this is unnecessary duplication and we can do better? Behold, the DependencyPropertyCache:
&lt;/p&gt;
&lt;pre class="c#" name="code"&gt;using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace SpaceRocks
{
    public class DependencyPropertyCache&amp;lt;T&amp;gt;
    {
        private DependencyProperty _dependencyProperty;
        private DependencyObject _parent;

        public DependencyPropertyCache(DependencyObject parent, DependencyProperty property)
        {
            if (parent == null)
                throw new ArgumentNullException(&amp;quot;parent&amp;quot;);
            if (property == null)
                throw new ArgumentNullException(&amp;quot;property&amp;quot;);

            _parent = parent;
            _dependencyProperty = property;
        }

        public T Value { get; private set; }

        public void SetValue(T value)
        {
            if (!Value.Equals(value))
            {
                _parent.SetValue(_dependencyProperty, value);
                this.Value = value;
            }
        }
    }
}&lt;/pre&gt;
&lt;p&gt;
Pretty simple, really. Now we can have cached values exposed by the &lt;em&gt;Value &lt;/em&gt;property
and update the value using &lt;em&gt;SetValue &lt;/em&gt;which does a comparison between old and
new, and only updates the actual dependency property if the new value is different.
Bill was using the inequality operator and this class is using the &lt;em&gt;Equals &lt;/em&gt;method
on System.Object, however it wouldn’t be very difficult to modify the cache to constrain
T to implementing IComparable&amp;lt;T&amp;gt;, as System.Double does, and/or a constructor
overload which might take a custom IComparable&amp;lt;T&amp;gt;. So far in the series, there
are only System.Double properties, so I’ve not done that yet.
&lt;/p&gt;
&lt;p&gt;
So now the modified code for the &lt;em&gt;Sprite &lt;/em&gt;class from &lt;a href="http://blogs.silverarcade.com/silverlight-games-101/14/silverlight-space-rocks-game-step-4-inheriting-from-sprite/"&gt;part
4&lt;/a&gt; looks like this:&amp;#160; 
&lt;/p&gt;
&lt;pre class="c#" name="code"&gt;using System.Windows.Controls;
using Microsoft.Xna.Framework;
using System.Windows;
using System.Windows.Media;

namespace SpaceRocks
{
    public class Sprite : Control
    {
        double dw = 0;
        double dh = 0; 
        static Vector2 gameSize = new Vector2(640, 480);
        private DependencyPropertyCache&amp;lt;double&amp;gt; _x;
        private DependencyPropertyCache&amp;lt;double&amp;gt; _y;
 
        public Sprite()
        {
            this.DefaultStyleKey = typeof(Sprite);
            this.SizeChanged += new SizeChangedEventHandler(Sprite_SizeChanged);
            _x = new DependencyPropertyCache&amp;lt;double&amp;gt;(this, Canvas.LeftProperty);
            _y = new DependencyPropertyCache&amp;lt;double&amp;gt;(this, Canvas.TopProperty);
        }

        void Sprite_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            Vector2 pos = Position;           
            
            _x.SetValue(double.NaN);
            _y.SetValue(double.NaN);

            Position = pos;
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            FrameworkElement element = VisualTreeHelper.GetChild(this, 0) as FrameworkElement;
            dw = element.Width / 2;
            dh = element.Height / 2;
            Width = element.Width;
            Height = element.Height;
        }

        public double X
        {
            get
            {
                return _x.Value;
            }
            set
            {
                _x.SetValue(value - dw);                
            }
        }

        public double Y
        {
            get
            {
                return _y.Value;
            }
            set
            {
                _y.SetValue(value - dh);                
            }
        }

        public Vector2 Position
        {
            get
            {
                return new Vector2( (float)_x.Value, (float)_y.Value);
            }
            set
            {
                _x.SetValue(value.X);
                _y.SetValue(value.Y);
            }
        }

        public Vector2 Velocity { get; set; }

        public void Update(double elapsedSeconds)
        {
            Position += Velocity * (float)elapsedSeconds;
            if (Position.X &amp;gt; gameSize.X) Position -= new Vector2(gameSize.X, 0);
            if (Position.X &amp;lt; 0) Position += new Vector2(gameSize.X, 0);
            if (Position.Y &amp;gt; gameSize.Y) Position -= new Vector2(0, gameSize.Y);
            if (Position.Y &amp;lt; 0) Position += new Vector2(0, gameSize.Y);
        }
    }
}&lt;/pre&gt;
&lt;p&gt;
Sweet.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.invalidoperation.com/aggbug.ashx?id=1acef3c4-1afa-49d6-9a16-5ff162726c9d" /&gt;</description>
      <comments>http://blog.invalidoperation.com/CommentView,guid,1acef3c4-1afa-49d6-9a16-5ff162726c9d.aspx</comments>
      <category>Silverlight</category>
    </item>
    <item>
      <trackback:ping>http://blog.invalidoperation.com/Trackback.aspx?guid=8e0564e1-3249-40ed-888b-c38a12726967</trackback:ping>
      <pingback:server>http://blog.invalidoperation.com/pingback.aspx</pingback:server>
      <pingback:target>http://blog.invalidoperation.com/PermaLink,guid,8e0564e1-3249-40ed-888b-c38a12726967.aspx</pingback:target>
      <dc:creator>Ray</dc:creator>
      <wfw:comment>http://blog.invalidoperation.com/CommentView,guid,8e0564e1-3249-40ed-888b-c38a12726967.aspx</wfw:comment>
      <wfw:commentRss>http://blog.invalidoperation.com/SyndicationService.asmx/GetEntryCommentsRss?guid=8e0564e1-3249-40ed-888b-c38a12726967</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I finally got around to playing with the bits for the Azure SDK, which as of this
writing is currently in <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=22703881-1197-49e5-8231-f49095cfd0bb&amp;displaylang=en">May
2009 CTP</a> mode. Here are some thoughts.
</p>
        <h5>Pretty good local development experience
</h5>
        <p>
Develop against a local cloud, deploy to the real one. The “role” stuff related to
the project types in Visual Studio is a little odd at first but once you get past
it, it’s the normal Asp.Net development experience we’ve had for a long time now,
at least until you want to use the Azure blob/queue/table-storage services.
</p>
        <h5>Hosting services
</h5>
        <p>
Literally, File –&gt; New Asp.Net Web Application –&gt; Publish –&gt; (Upload via
Azure portal) –&gt; done. Definitely was not expecting this to be so straight forward.
Should be really easy to migrate existing Asp.Net sites to the cloud, providing they
comply with Azure’s security posture.
</p>
        <h5>There’s a real over-reliance on the StorageClient sample.
</h5>
        <p>
          <em>Every </em>sample or piece of code for demonstrating developing against Azure
is using the StorageClient library, which is one of the sample projects that ships
with the Azure SDK. There are numerous posts out there saying it is <a href="http://oakleafblog.blogspot.com/2009/01/azure-storage-services-storage-client.html">not
to be considered an official API</a>, and that the REST APIs are the real deal. That’s
fantastic, but I don’t think any developer is interesting in writing a bunch of HttpWebRequest-heavy
code to use Azure or worse, build out their own end to end wrapper to the REST interfaces.
Sure, if no official libraries are published, some usable ones will surely pop up
on <a href="http://www.codeplex.com">CodePlex</a> but I don’t see how Microsoft would
even consider not providing an official .Net API, given what it could potentially
do related to adoption of their platform. Microsoft has historically been very pro-RAD
in its development platform and tooling, and this is contrary to that, which is puzzling.
I mean, one might half-expect to see a TableStorageDataSource control for WebForms.
Instead, it sounds like there will be nothing but some docs on MSDN describing the
REST calls.
</p>
        <h5>Table Storage != <em>table storage</em>. 
</h5>
        <p>
          <em>Table Storage</em> has a strong connotation for “relational”, and Azure’s Table
Storage is anything but. It really should be called <em>Structured Blob Storage, </em>because
that’s basically what it is, storing a structured property bag instead of an unstructured
blob of ones and zeros. Trying to develop a simple “Post has many Comments” example
lead me down a path where I:
</p>
        <ol>
        </ol>
        <ol>
          <li>
Chose Guids as object-keys. Since this is off-premises and not bound to a strict schema,
there is no options for auto-incremented properties. You either handle it yourself
at the application level or find a better way to handle uniqueness among your entities.
Guid.NewGuid() to the rescue. 
</li>
          <li>
Realized I either don’t “get” Table Storage and/or <em>I’m doing it wrong. </em><a href="http://msdn.microsoft.com/en-us/library/dd135725.aspx">The
LINQ capabilities of table storage extend to 4 LINQ operators.</a>  And of those,
only the most basic ones. Better support for Take, combined with support for Skip
and OrderBy/OrderByDescending would at least provide the foundation of something usable
from a querying perspective. I get that it’s not relational, so joining and grouping
are probably overkill, but not being able to get the second set of 50 posts sorted
by publish date, without fetching all of them and doing it in-memory? Come on. Taking
the effort to develop against table storage to leverage the scalability and availability
does not make sense when you have to fetch a whole ton of entities only to do a bunch
of manipulation in memory in order to send just the right ones back to the client/browser. 
</li>
        </ol>
        <p>
Because of the querying limitations, the only way I think I would use Table Storage
in an Azure-centric application with non-trivial storage requirements would be to
use it as a structured cache for highly-requested or relatively static data. The rest
would come from or something else entirely, possibly Sql Azure, <a href="http://blogs.msdn.com/ssds/archive/2009/07/09/9827971.aspx">formerly
Sql Data Services</a>. Of course, Sql Azure isn’t available in any sort of CTP or
preview, so the jury is out on that one.
</p>
        <h5>Blob storage 
</h5>
        <p>
This is the strongest part of the Azure platform as I see it today. Even with the
over-reliance on the StorageClient sample, shoving files up to Azure to get reliable,
scalable file hosting is one area I think will really shine.
</p>
        <h5>No development support for Windows XP
</h5>
        <p>
This is kind of lame, in my opinion. But it will sting less when Windows 7 is out
as I suspect a ton of people will be moving to that directly from XP. 
</p>
        <p>
 
</p>
        <p>
Overall, I really do like the platform from a development standpoint. Looking forward
to what comes out surrounding it during PDC later this year.
</p>
        <img width="0" height="0" src="http://blog.invalidoperation.com/aggbug.ashx?id=8e0564e1-3249-40ed-888b-c38a12726967" />
      </body>
      <title>Weekend Dabbling: Developing Against Windows Azure</title>
      <guid isPermaLink="false">http://blog.invalidoperation.com/PermaLink,guid,8e0564e1-3249-40ed-888b-c38a12726967.aspx</guid>
      <link>http://blog.invalidoperation.com/2009/07/12/WeekendDabblingDevelopingAgainstWindowsAzure.aspx</link>
      <pubDate>Sun, 12 Jul 2009 21:29:05 GMT</pubDate>
      <description>&lt;p&gt;
I finally got around to playing with the bits for the Azure SDK, which as of this
writing is currently in &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=22703881-1197-49e5-8231-f49095cfd0bb&amp;amp;displaylang=en"&gt;May
2009 CTP&lt;/a&gt; mode. Here are some thoughts.
&lt;/p&gt;
&lt;h5&gt;Pretty good local development experience
&lt;/h5&gt;
&lt;p&gt;
Develop against a local cloud, deploy to the real one. The “role” stuff related to
the project types in Visual Studio is a little odd at first but once you get past
it, it’s the normal Asp.Net development experience we’ve had for a long time now,
at least until you want to use the Azure blob/queue/table-storage services.
&lt;/p&gt;
&lt;h5&gt;Hosting services
&lt;/h5&gt;
&lt;p&gt;
Literally, File –&amp;gt; New Asp.Net Web Application –&amp;gt; Publish –&amp;gt; (Upload via
Azure portal) –&amp;gt; done. Definitely was not expecting this to be so straight forward.
Should be really easy to migrate existing Asp.Net sites to the cloud, providing they
comply with Azure’s security posture.
&lt;/p&gt;
&lt;h5&gt;There’s a real over-reliance on the StorageClient sample.
&lt;/h5&gt;
&lt;p&gt;
&lt;em&gt;Every &lt;/em&gt;sample or piece of code for demonstrating developing against Azure
is using the StorageClient library, which is one of the sample projects that ships
with the Azure SDK. There are numerous posts out there saying it is &lt;a href="http://oakleafblog.blogspot.com/2009/01/azure-storage-services-storage-client.html"&gt;not
to be considered an official API&lt;/a&gt;, and that the REST APIs are the real deal. That’s
fantastic, but I don’t think any developer is interesting in writing a bunch of HttpWebRequest-heavy
code to use Azure or worse, build out their own end to end wrapper to the REST interfaces.
Sure, if no official libraries are published, some usable ones will surely pop up
on &lt;a href="http://www.codeplex.com"&gt;CodePlex&lt;/a&gt; but I don’t see how Microsoft would
even consider not providing an official .Net API, given what it could potentially
do related to adoption of their platform. Microsoft has historically been very pro-RAD
in its development platform and tooling, and this is contrary to that, which is puzzling.
I mean, one might half-expect to see a TableStorageDataSource control for WebForms.
Instead, it sounds like there will be nothing but some docs on MSDN describing the
REST calls.
&lt;/p&gt;
&lt;h5&gt;Table Storage != &lt;em&gt;table storage&lt;/em&gt;. 
&lt;/h5&gt;
&lt;p&gt;
&lt;em&gt;Table Storage&lt;/em&gt; has a strong connotation for “relational”, and Azure’s Table
Storage is anything but. It really should be called &lt;em&gt;Structured Blob Storage, &lt;/em&gt;because
that’s basically what it is, storing a structured property bag instead of an unstructured
blob of ones and zeros. Trying to develop a simple “Post has many Comments” example
lead me down a path where I:
&lt;/p&gt;
&lt;ol&gt;
&lt;ol&gt;
&lt;li&gt;
Chose Guids as object-keys. Since this is off-premises and not bound to a strict schema,
there is no options for auto-incremented properties. You either handle it yourself
at the application level or find a better way to handle uniqueness among your entities.
Guid.NewGuid() to the rescue. 
&lt;/li&gt;
&lt;li&gt;
Realized I either don’t “get” Table Storage and/or &lt;em&gt;I’m doing it wrong. &lt;/em&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/dd135725.aspx"&gt;The
LINQ capabilities of table storage extend to 4 LINQ operators.&lt;/a&gt;&amp;#160; And of those,
only the most basic ones. Better support for Take, combined with support for Skip
and OrderBy/OrderByDescending would at least provide the foundation of something usable
from a querying perspective. I get that it’s not relational, so joining and grouping
are probably overkill, but not being able to get the second set of 50 posts sorted
by publish date, without fetching all of them and doing it in-memory? Come on. Taking
the effort to develop against table storage to leverage the scalability and availability
does not make sense when you have to fetch a whole ton of entities only to do a bunch
of manipulation in memory in order to send just the right ones back to the client/browser. 
&lt;/li&gt;
&lt;/ol&gt;
&gt;
&lt;p&gt;
Because of the querying limitations, the only way I think I would use Table Storage
in an Azure-centric application with non-trivial storage requirements would be to
use it as a structured cache for highly-requested or relatively static data. The rest
would come from or something else entirely, possibly Sql Azure, &lt;a href="http://blogs.msdn.com/ssds/archive/2009/07/09/9827971.aspx"&gt;formerly
Sql Data Services&lt;/a&gt;. Of course, Sql Azure isn’t available in any sort of CTP or
preview, so the jury is out on that one.
&lt;/p&gt;
&lt;h5&gt;Blob storage 
&lt;/h5&gt;
&lt;p&gt;
This is the strongest part of the Azure platform as I see it today. Even with the
over-reliance on the StorageClient sample, shoving files up to Azure to get reliable,
scalable file hosting is one area I think will really shine.
&lt;/p&gt;
&lt;h5&gt;No development support for Windows XP
&lt;/h5&gt;
&lt;p&gt;
This is kind of lame, in my opinion. But it will sting less when Windows 7 is out
as I suspect a ton of people will be moving to that directly from XP. 
&lt;/p&gt;
&lt;p&gt;
&amp;#160;
&lt;/p&gt;
&lt;p&gt;
Overall, I really do like the platform from a development standpoint. Looking forward
to what comes out surrounding it during PDC later this year.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.invalidoperation.com/aggbug.ashx?id=8e0564e1-3249-40ed-888b-c38a12726967" /&gt;</description>
      <comments>http://blog.invalidoperation.com/CommentView,guid,8e0564e1-3249-40ed-888b-c38a12726967.aspx</comments>
      <category>Azure</category>
    </item>
    <item>
      <trackback:ping>http://blog.invalidoperation.com/Trackback.aspx?guid=a6234512-a1e7-46c2-a582-c4aa3f34bdb6</trackback:ping>
      <pingback:server>http://blog.invalidoperation.com/pingback.aspx</pingback:server>
      <pingback:target>http://blog.invalidoperation.com/PermaLink,guid,a6234512-a1e7-46c2-a582-c4aa3f34bdb6.aspx</pingback:target>
      <dc:creator>Ray</dc:creator>
      <wfw:comment>http://blog.invalidoperation.com/CommentView,guid,a6234512-a1e7-46c2-a582-c4aa3f34bdb6.aspx</wfw:comment>
      <wfw:commentRss>http://blog.invalidoperation.com/SyndicationService.asmx/GetEntryCommentsRss?guid=a6234512-a1e7-46c2-a582-c4aa3f34bdb6</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Of all the controls in the Asp.Net WebForms family I think I like the ObjectDataSource
the most. It’s a shiny beacon of hope in a framework otherwise bogged down by the
perils of ViewState, heavy and un-testable infrastructure classes, and much to be
desired in terms of abstractions. I know everyone else is all about the MVC angle
bracket soup these days but for those (stuck or by choice) in WebForms land, ODS is
fantastic. What it allows you to do, in short, is to make often awkward data-binding
your bitch. Let’s see how.
</p>
        <p>
The essence of all data source controls is allowing you, the developer, to short-circuit
traditional architectural techniques like layering and get to having working CRUD
in a very just-let-me-get-this-done-and-go-home-what-do-you-mean-unit-testing fashion.
SqlDataSource goes direct to a database, XmlDataSource goes to xml, and so on. ObjectDataSource
is the only one that lets you break out of the 2-tier forms-over-data model that Microsoft
likes to push. But what about LinqDataSource? Well, ODS works by binding to methods
on a specified class in your code. Which, since it’s your code, allows you much more
freedom than any other the others, including the LinqDataSource. Want to provide a
specific instance of the binding class to be consumed by the ODS at runtime by your
DI container of choice? Want to invoke custom business logic or validation during
the CRUD binding-calls? Want to use constructor injection and make your binding class
actually, you know, testable? Want to actually put code in a place other than an web
form’s code-behind? Want to leverage server-side paging in Linq to Sql to only fetch
and display the data you’re concerned with showing? Want to pipe in some custom data
from the http cache? All doable with ODS, the others not so much.
</p>
        <p>
For a class to serve as a binding source for an ObjectDataSource, it needs:
</p>
        <ol>
          <li>
One or more methods to return stuff to bind against. Business objects, a DataTable,
whatever. These methods can optionally have 
<ul><li>
Two integer parameters for paging (defaulting to ‘maximumRows’ and ‘startRowIndex’)
indicating a subset of data to be returned 
</li><li>
A string parameter for sorting, provided in the form of C<strong>olumnName DIRECTION</strong> such
as <em>ProductName ASC</em> or <em>UnitPrice DESC</em></li></ul></li>
          <li>
A public constructor. Unless you subscribe to the ObjectDataSource’s <em>ObjectCreating </em>event
in order to provide a custom instance before the binding calls are executed. 
</li>
          <li>
A public method that returns the total number of rows not including the fetched-page
size. This is only necessary if your ODS has EnablePaging set to true. 
</li>
          <li>
Some attributes on the class or methods that do nothing but tell Visual Studio HEY!
SHOW ME AS BINDABLE. Technically these are optional. 
</li>
        </ol>
        <p>
Which, in the case of Northwind might look like:
</p>
        <pre class="c#" name="code">using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using Northwind.Model;

namespace Northwind.DataBinding
{
    [DataObject(true)]
    public class ProductQuerySource : IDisposable
    {
        private NorthwindDataContext _dataContext;
        private bool _disposeContextWhenDone = false;
        private int _count = 0;

        public ProductQuerySource(NorthwindDataContext dataContext)
        {
            if (dataContext == null)
                throw new ArgumentNullException("dataContext");
            
            _dataContext = dataContext;
        }

        public ProductQuerySource()
            : this(new NorthwindDataContext())
        {
            _disposeContextWhenDone = true;
        }

        [DataObjectMethod(DataObjectMethodType.Select)]
        public IList<product>
FetchAll(int startAt, int pageSize) { _count = _dataContext.Products.Count(); var
query = _dataContext.Products.Skip(startAt).Take(pageSize).ToList(); return query;
} [DataObjectMethod(DataObjectMethodType.Select)] public IList<product>
FetchAll(int startAt, int pageSize, string sortExpression) { _count = _dataContext.Products.Count();
IQueryable<product>
products = _dataContext.Products; if (!string.IsNullOrEmpty(sortExpression)) products
= _dataContext.Products.OrderBy(sortExpression); return products.Skip(startAt).Take(pageSize).ToList();
} public int GetCount() { return _count; } public void Dispose() { if (_disposeContextWhenDone)
_dataContext.Dispose(); } } }
</product></product></product></pre>
        <p>
With our ObjectDataSource markup resembling
</p>
        <pre class="xml" name="code">&lt;asp:ObjectDataSource ID="odsNorthwindProducts" runat="server" 
        OldValuesParameterFormatString="original_{0}" 
        SelectMethod="FetchAll" TypeName="Northwind.DataBinding.ProductQuerySource"
        EnablePaging="true"
        MaximumRowsParameterName="pageSize" 
        StartRowIndexParameterName="startAt" 
        SelectCountMethod="GetCount" SortParameterName="sortExpression"&gt;
    &lt;/asp:ObjectDataSource&gt;</pre>
        <p>
Link that sucker to a GridView with <em>AllowPaging</em> and <em>AllowSorting</em> both
set to “true” and you’ll get a grid displaying Products in which only the products
currently being rendered are even returned from the database. Click on a column header
to sort? Current paged fetched and sorted in database. Fantastic. Note that standard
parameter-binding applies here as well, Fetch() could easily have a <em>categoryid </em>parameter
which might limit the results to all Products in that category. Since its all just
methods on a class, our binding class can be tested using whatever the your testing
strategy of choice happens to be.
</p>
        <p>
Oh, but what about that pesky sorting? We can’t sort a linq query by a string, can
we? Well, yeah, normally that would be the case, but not to fear, because but by taking
a bit of code based on <a href="http://technoesis.wordpress.com/2008/03/03/linq-to-sql-dynamic-sorting-without-using-complete-dynamic-linq-libraries/">this</a> post
by Pradeep Mishra (which has alot of typos in the code there, beware) we’ll be able
to dynamically use those string sort expressions to invoke Linq’s OrderBy and OrderByDescending
methods. Which, in the case of Linq to Sql, will result in the respective ORDER BY
clauses being added to the query once it is executed against the database.
</p>
        <pre class="c#" name="code">using System;
using System.Linq.Expressions;

namespace System.Linq
{
    public static class LinqExtensions
    {
        public static IQueryable&lt;TEntity&gt; OrderBy&lt;TEntity&gt;(this IQueryable&lt;TEntity&gt; source, string sortExpression) where TEntity : class
        {
            if (string.IsNullOrEmpty(sortExpression))
                return source; // nothing to sort on

            var entityType = typeof(TEntity);
            string ascSortMethodName = "OrderBy";
            string descSortMethodName = "OrderByDescending";            
            string[] sortExpressionParts = sortExpression.Split(' ');
            string sortProperty = sortExpressionParts[0];
            string sortMethod = ascSortMethodName;

            if (sortExpressionParts.Length &gt; 1 &amp;&amp; sortExpressionParts[1] == "DESC")
                sortMethod = descSortMethodName;    

            var property = entityType.GetProperty(sortProperty);
            var parameter = Expression.Parameter(entityType, "p");
            var propertyAccess = Expression.MakeMemberAccess(parameter, property);
            var orderByExp = Expression.Lambda(propertyAccess, parameter);

            MethodCallExpression resultExp = Expression.Call(
                                                typeof(Queryable), 
                                                sortMethod, 
                                                new Type[] { entityType, property.PropertyType },
                                                source.Expression, 
                                                Expression.Quote(orderByExp));

            return source.Provider.CreateQuery&lt;TEntity&gt;(resultExp);
        }
    }
}</pre>
        <p>
So having that in place means we can have SortParameterName=”sortDirection” in our
ODS markup as well as the sortDirection string parameter on the binding method. Hello,
server-side paging and sorting.
</p>
        <p>
I should note that this sorting and paging isn’t unique to Linq To Sql- it applies
to anything queryable by Linq. It’s just that leveraging this approach with Linq To
Sql yields for a more elegant sorting and paging solution when working with a database
than some other the other switch-based or (god forbid) stored-procedure based approaches.
</p>
        <img width="0" height="0" src="http://blog.invalidoperation.com/aggbug.ashx?id=a6234512-a1e7-46c2-a582-c4aa3f34bdb6" />
      </body>
      <title>Linq to Sql and ObjectDataSource: BFF</title>
      <guid isPermaLink="false">http://blog.invalidoperation.com/PermaLink,guid,a6234512-a1e7-46c2-a582-c4aa3f34bdb6.aspx</guid>
      <link>http://blog.invalidoperation.com/2009/07/12/LinqToSqlAndObjectDataSourceBFF.aspx</link>
      <pubDate>Sun, 12 Jul 2009 06:41:46 GMT</pubDate>
      <description>&lt;p&gt;
Of all the controls in the Asp.Net WebForms family I think I like the ObjectDataSource
the most. It’s a shiny beacon of hope in a framework otherwise bogged down by the
perils of ViewState, heavy and un-testable infrastructure classes, and much to be
desired in terms of abstractions. I know everyone else is all about the MVC angle
bracket soup these days but for those (stuck or by choice) in WebForms land, ODS is
fantastic. What it allows you to do, in short, is to make often awkward data-binding
your bitch. Let’s see how.
&lt;/p&gt;
&lt;p&gt;
The essence of all data source controls is allowing you, the developer, to short-circuit
traditional architectural techniques like layering and get to having working CRUD
in a very just-let-me-get-this-done-and-go-home-what-do-you-mean-unit-testing fashion.
SqlDataSource goes direct to a database, XmlDataSource goes to xml, and so on. ObjectDataSource
is the only one that lets you break out of the 2-tier forms-over-data model that Microsoft
likes to push. But what about LinqDataSource? Well, ODS works by binding to methods
on a specified class in your code. Which, since it’s your code, allows you much more
freedom than any other the others, including the LinqDataSource. Want to provide a
specific instance of the binding class to be consumed by the ODS at runtime by your
DI container of choice? Want to invoke custom business logic or validation during
the CRUD binding-calls? Want to use constructor injection and make your binding class
actually, you know, testable? Want to actually put code in a place other than an web
form’s code-behind? Want to leverage server-side paging in Linq to Sql to only fetch
and display the data you’re concerned with showing? Want to pipe in some custom data
from the http cache? All doable with ODS, the others not so much.
&lt;/p&gt;
&lt;p&gt;
For a class to serve as a binding source for an ObjectDataSource, it needs:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
One or more methods to return stuff to bind against. Business objects, a DataTable,
whatever. These methods can optionally have 
&lt;ul&gt;
&lt;li&gt;
Two integer parameters for paging (defaulting to ‘maximumRows’ and ‘startRowIndex’)
indicating a subset of data to be returned 
&lt;/li&gt;
&lt;li&gt;
A string parameter for sorting, provided in the form of C&lt;strong&gt;olumnName DIRECTION&lt;/strong&gt; such
as &lt;em&gt;ProductName ASC&lt;/em&gt; or &lt;em&gt;UnitPrice DESC&lt;/em&gt; 
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
A public constructor. Unless you subscribe to the ObjectDataSource’s &lt;em&gt;ObjectCreating &lt;/em&gt;event
in order to provide a custom instance before the binding calls are executed. 
&lt;/li&gt;
&lt;li&gt;
A public method that returns the total number of rows not including the fetched-page
size. This is only necessary if your ODS has EnablePaging set to true. 
&lt;/li&gt;
&lt;li&gt;
Some attributes on the class or methods that do nothing but tell Visual Studio HEY!
SHOW ME AS BINDABLE. Technically these are optional. 
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
Which, in the case of Northwind might look like:
&lt;/p&gt;
&lt;pre class="c#" name="code"&gt;using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using Northwind.Model;

namespace Northwind.DataBinding
{
    [DataObject(true)]
    public class ProductQuerySource : IDisposable
    {
        private NorthwindDataContext _dataContext;
        private bool _disposeContextWhenDone = false;
        private int _count = 0;

        public ProductQuerySource(NorthwindDataContext dataContext)
        {
            if (dataContext == null)
                throw new ArgumentNullException(&amp;quot;dataContext&amp;quot;);
            
            _dataContext = dataContext;
        }

        public ProductQuerySource()
            : this(new NorthwindDataContext())
        {
            _disposeContextWhenDone = true;
        }

        [DataObjectMethod(DataObjectMethodType.Select)]
        public IList&lt;product&gt;
FetchAll(int startAt, int pageSize) { _count = _dataContext.Products.Count(); var
query = _dataContext.Products.Skip(startAt).Take(pageSize).ToList(); return query;
} [DataObjectMethod(DataObjectMethodType.Select)] public IList&lt;product&gt;
FetchAll(int startAt, int pageSize, string sortExpression) { _count = _dataContext.Products.Count();
IQueryable&lt;product&gt;
products = _dataContext.Products; if (!string.IsNullOrEmpty(sortExpression)) products
= _dataContext.Products.OrderBy(sortExpression); return products.Skip(startAt).Take(pageSize).ToList();
} public int GetCount() { return _count; } public void Dispose() { if (_disposeContextWhenDone)
_dataContext.Dispose(); } } }
&lt;/pre&gt;
&lt;p&gt;
With our ObjectDataSource markup resembling
&lt;/p&gt;
&lt;pre class="xml" name="code"&gt;&amp;lt;asp:ObjectDataSource ID=&amp;quot;odsNorthwindProducts&amp;quot; runat=&amp;quot;server&amp;quot; 
        OldValuesParameterFormatString=&amp;quot;original_{0}&amp;quot; 
        SelectMethod=&amp;quot;FetchAll&amp;quot; TypeName=&amp;quot;Northwind.DataBinding.ProductQuerySource&amp;quot;
        EnablePaging=&amp;quot;true&amp;quot;
        MaximumRowsParameterName=&amp;quot;pageSize&amp;quot; 
        StartRowIndexParameterName=&amp;quot;startAt&amp;quot; 
        SelectCountMethod=&amp;quot;GetCount&amp;quot; SortParameterName=&amp;quot;sortExpression&amp;quot;&amp;gt;
    &amp;lt;/asp:ObjectDataSource&amp;gt;&lt;/pre&gt;
&lt;p&gt;
Link that sucker to a GridView with &lt;em&gt;AllowPaging&lt;/em&gt; and &lt;em&gt;AllowSorting&lt;/em&gt; both
set to “true” and you’ll get a grid displaying Products in which only the products
currently being rendered are even returned from the database. Click on a column header
to sort? Current paged fetched and sorted in database. Fantastic. Note that standard
parameter-binding applies here as well, Fetch() could easily have a &lt;em&gt;categoryid &lt;/em&gt;parameter
which might limit the results to all Products in that category. Since its all just
methods on a class, our binding class can be tested using whatever the your testing
strategy of choice happens to be.
&lt;/p&gt;
&lt;p&gt;
Oh, but what about that pesky sorting? We can’t sort a linq query by a string, can
we? Well, yeah, normally that would be the case, but not to fear, because but by taking
a bit of code based on &lt;a href="http://technoesis.wordpress.com/2008/03/03/linq-to-sql-dynamic-sorting-without-using-complete-dynamic-linq-libraries/"&gt;this&lt;/a&gt; post
by Pradeep Mishra (which has alot of typos in the code there, beware) we’ll be able
to dynamically use those string sort expressions to invoke Linq’s OrderBy and OrderByDescending
methods. Which, in the case of Linq to Sql, will result in the respective ORDER BY
clauses being added to the query once it is executed against the database.
&lt;/p&gt;
&lt;pre class="c#" name="code"&gt;using System;
using System.Linq.Expressions;

namespace System.Linq
{
    public static class LinqExtensions
    {
        public static IQueryable&amp;lt;TEntity&amp;gt; OrderBy&amp;lt;TEntity&amp;gt;(this IQueryable&amp;lt;TEntity&amp;gt; source, string sortExpression) where TEntity : class
        {
            if (string.IsNullOrEmpty(sortExpression))
                return source; // nothing to sort on

            var entityType = typeof(TEntity);
            string ascSortMethodName = &amp;quot;OrderBy&amp;quot;;
            string descSortMethodName = &amp;quot;OrderByDescending&amp;quot;;            
            string[] sortExpressionParts = sortExpression.Split(' ');
            string sortProperty = sortExpressionParts[0];
            string sortMethod = ascSortMethodName;

            if (sortExpressionParts.Length &amp;gt; 1 &amp;amp;&amp;amp; sortExpressionParts[1] == &amp;quot;DESC&amp;quot;)
                sortMethod = descSortMethodName;    

            var property = entityType.GetProperty(sortProperty);
            var parameter = Expression.Parameter(entityType, &amp;quot;p&amp;quot;);
            var propertyAccess = Expression.MakeMemberAccess(parameter, property);
            var orderByExp = Expression.Lambda(propertyAccess, parameter);

            MethodCallExpression resultExp = Expression.Call(
                                                typeof(Queryable), 
                                                sortMethod, 
                                                new Type[] { entityType, property.PropertyType },
                                                source.Expression, 
                                                Expression.Quote(orderByExp));

            return source.Provider.CreateQuery&amp;lt;TEntity&amp;gt;(resultExp);
        }
    }
}&lt;/pre&gt;
&lt;p&gt;
So having that in place means we can have SortParameterName=”sortDirection” in our
ODS markup as well as the sortDirection string parameter on the binding method. Hello,
server-side paging and sorting.
&lt;/p&gt;
&lt;p&gt;
I should note that this sorting and paging isn’t unique to Linq To Sql- it applies
to anything queryable by Linq. It’s just that leveraging this approach with Linq To
Sql yields for a more elegant sorting and paging solution when working with a database
than some other the other switch-based or (god forbid) stored-procedure based approaches.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.invalidoperation.com/aggbug.ashx?id=a6234512-a1e7-46c2-a582-c4aa3f34bdb6" /&gt;</description>
      <comments>http://blog.invalidoperation.com/CommentView,guid,a6234512-a1e7-46c2-a582-c4aa3f34bdb6.aspx</comments>
      <category>Asp.Net</category>
      <category>data binding</category>
      <category>database</category>
      <category>Linq to Sql</category>
      <category>Sql Server</category>
    </item>
    <item>
      <trackback:ping>http://blog.invalidoperation.com/Trackback.aspx?guid=0c698fee-cd98-428d-81d5-1b35ea521552</trackback:ping>
      <pingback:server>http://blog.invalidoperation.com/pingback.aspx</pingback:server>
      <pingback:target>http://blog.invalidoperation.com/PermaLink,guid,0c698fee-cd98-428d-81d5-1b35ea521552.aspx</pingback:target>
      <dc:creator>Ray</dc:creator>
      <wfw:comment>http://blog.invalidoperation.com/CommentView,guid,0c698fee-cd98-428d-81d5-1b35ea521552.aspx</wfw:comment>
      <wfw:commentRss>http://blog.invalidoperation.com/SyndicationService.asmx/GetEntryCommentsRss?guid=0c698fee-cd98-428d-81d5-1b35ea521552</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://blog.invalidoperation.com/content/binary/WindowsLiveWriter/FunwithLinqtoSchema_1488A/schemaservice_2.jpg">
            <img title="schemaservice" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="497" alt="schemaservice" src="http://blog.invalidoperation.com/content/binary/WindowsLiveWriter/FunwithLinqtoSchema_1488A/schemaservice_thumb.jpg" width="663" border="0" />
          </a>
        </p>
        <p>
What, you mean you <em>don’t</em> expose your database metadata via an Ado.Net data
service?
</p>
        <img width="0" height="0" src="http://blog.invalidoperation.com/aggbug.ashx?id=0c698fee-cd98-428d-81d5-1b35ea521552" />
      </body>
      <title>Fun with Linq to Schema</title>
      <guid isPermaLink="false">http://blog.invalidoperation.com/PermaLink,guid,0c698fee-cd98-428d-81d5-1b35ea521552.aspx</guid>
      <link>http://blog.invalidoperation.com/2009/04/12/FunWithLinqToSchema.aspx</link>
      <pubDate>Sun, 12 Apr 2009 03:40:25 GMT</pubDate>
      <description>&lt;p&gt;
&lt;a href="http://blog.invalidoperation.com/content/binary/WindowsLiveWriter/FunwithLinqtoSchema_1488A/schemaservice_2.jpg"&gt;&lt;img title="schemaservice" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="497" alt="schemaservice" src="http://blog.invalidoperation.com/content/binary/WindowsLiveWriter/FunwithLinqtoSchema_1488A/schemaservice_thumb.jpg" width="663" border="0" /&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
What, you mean you &lt;em&gt;don’t&lt;/em&gt; expose your database metadata via an Ado.Net data
service?
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.invalidoperation.com/aggbug.ashx?id=0c698fee-cd98-428d-81d5-1b35ea521552" /&gt;</description>
      <comments>http://blog.invalidoperation.com/CommentView,guid,0c698fee-cd98-428d-81d5-1b35ea521552.aspx</comments>
      <category>meta</category>
      <category>metadata</category>
    </item>
    <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>
    <item>
      <trackback:ping>http://blog.invalidoperation.com/Trackback.aspx?guid=5b20c588-314d-4ce2-b9f1-ed07b4fb7793</trackback:ping>
      <pingback:server>http://blog.invalidoperation.com/pingback.aspx</pingback:server>
      <pingback:target>http://blog.invalidoperation.com/PermaLink,guid,5b20c588-314d-4ce2-b9f1-ed07b4fb7793.aspx</pingback:target>
      <dc:creator>Ray</dc:creator>
      <wfw:comment>http://blog.invalidoperation.com/CommentView,guid,5b20c588-314d-4ce2-b9f1-ed07b4fb7793.aspx</wfw:comment>
      <wfw:commentRss>http://blog.invalidoperation.com/SyndicationService.asmx/GetEntryCommentsRss?guid=5b20c588-314d-4ce2-b9f1-ed07b4fb7793</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
For most ORM or data layer utilities there is some component of code generation involved
and somewhere along the line retrieving some metadata about the underlying structure
of a database is usually involved. Seeing as it relates to <a href="http://blog.invalidoperation.com/2008/12/11/CurrentProjectNDeavor.aspx">NDeavor</a>,
I figured I’d write about the ins and outs of getting metadata when running close
to the database. Basically, there are a few basic ways to access database specific
metadata directly through .Net.
</p>
        <h5>Vendor-specific API.
</h5>
        <p>
I only know of one comprehensive API for this and it’s <a href="http://www.microsoft.com/downloads/details.aspx?familyid=d09c1d60-a13c-4479-9b91-9e8b9d835cdc&amp;displaylang=en">Sql
Management Objects (SMO)</a> which is Sql-Server only. A tremendously useful API for
any Microsoft-dominated shops, though. Enumerating through basic structures like tables
and columns is incredibly easy, if a little slow. Getting the table name, column name,
and data type name of every column in every table in the <a href="http://www.codeplex.com/ChinookDatabase">chinook</a> database
might look like this:
</p>
        <pre class="c#" name="code">public void PrintChinookTableColumns()
{
    ServerConnection sc = new ServerConnection(@".\SQLEXPRESS");
    sc.Connect();
    Server server = new Server(sc);
    Database chinookDb = server.Databases["chinook"];
    server.SetDefaultInitFields(typeof(Table), "IsSystemObject");
    foreach (Table table in chinookDb.Tables)
    {
        if (table.IsSystemObject)
            continue;

        string tableName = table.Name;

        foreach (Column col in table.Columns)
        {
            string columnName = col.Name;
            string dataTypeName = col.DataType.Name;

            Console.WriteLine("{0} {1} {2}", tableName, columnName, dataTypeName);
        }
    }
    sc.Disconnect();
}</pre>
        <p>
 
</p>
        <h5>Querying vendor-specific system tables. 
</h5>
        <p>
          <strong>
          </strong>Vendor lock-in at it’s finest, and typically unsupported at that.
Usefulness is dependent on what level of information is available and the amount of
time you’re willing to spend figuring out what the various columns and values mean.
Getting table, column, and data type names in a specific database in Sql Server Express
2005 might look like this:
</p>
        <pre class="sql" name="code">use chinook
go

SELECT  T.name as TableName, 
        C.name as ColumnName,
        ST.name as DataType
FROM 
    sys.tables T 
    INNER JOIN sys.columns C on T.object_id = C.object_id
    INNER JOIN sys.systypes ST on C.system_type_id = ST.type</pre>
        <h5> 
</h5>
        <h5>Querying <em>standard</em> metadata tables.
</h5>
        <p>
          <strong>
          </strong>Emphasis on ‘standard’, because there really is none. There is a
spec as part of the SQL standards that came along sometime around SQL92/SQL99 (not
sure) which dictates the INFORMATION_SCHEMA tables which store very basic metadata
about the tables, views, columns, procedures, functions, parameters, constraints,
etc, of a specific relational database. Support for these is relative to how much
the vendor cares about doing so. Sql Server and MySql both have pretty strong support
for these. But even then, the spec is very loose and while simple queries to say,
get all table names and column names, might be portable, more complex ones likely
won’t be. There’s other discrepancies as well, for instance the verbiage around ‘schema’
and ‘catalog’. In MySql terms <em>schema</em> is analogous to a Sql Server <em>database</em>,
and this translates down into their implementation of these metadata tables. Back
to the example of tables, columns, and data types in the chinook database:
</p>
        <pre class="sql" name="code">Sql Server: 
use chinook 
go 

SELECT 
    T.TABLE_NAME as TableName,    
    C.COLUMN_NAME as ColumnName, 
    C.DATA_TYPE as DataType 
FROM 
    INFORMATION_SCHEMA.TABLES T 
    INNER JOIN INFORMATION_SCHEMA.COLUMNS C ON 
        T.TABLE_NAME = C.TABLE_NAME AND 
        T.TABLE_SCHEMA = C.TABLE_SCHEMA AND 
        T.TABLE_CATALOG = C.TABLE_CATALOG

 

MySql: 
SELECT 
    T.TABLE_NAME as TableName, 
    C.COLUMN_NAME as ColumnName, 
    C.DATA_TYPE as DataType 
FROM 
    INFORMATION_SCHEMA.TABLES T 
    INNER JOIN INFORMATION_SCHEMA.COLUMNS C ON 
        T.TABLE_NAME = C.TABLE_NAME AND 
        T.TABLE_SCHEMA = C.TABLE_SCHEMA 
WHERE T.TABLE_SCHEMA = 'chinook';</pre>
        <h5> 
</h5>
        <h5>Using the schema-related functionality in Ado.Net 2.0. 
</h5>
        <p>
Introduced in .Net 2.0, the DbConnection base class has a method with a few overloads
called GetSchema(). This is supposed to allow implementers of Ado.Net providers a
way to provide metadata about the underlying connected data store. Since it’s not
strongly typed, and consists of returning DataTables, it’s entirely up to the implementer
as far as what information is provided. Typically calling the parameter-less version
of GetSchema() would return a DataTable that describes what metadata is available,
indicated by a string column called something like <em>MetaDataCollection</em> in
which you can pass to subsequent calls to GetSchema(string) to get that specific chunk
of metadata. There’s a decent write up of what’s available in the native Ado.Net providers
located <a href="http://msdn.microsoft.com/en-us/library/kcax58fh.aspx">here</a>.
Here’s an extension method to get all the metadata into one dataset for further manipulation,
which should work for the built-in Ado.Net providers, as well as MySql.Data.MysqlClient
using the latest <a href="http://dev.mysql.com/downloads/connector/net/5.2.html">MySql
Net Connector</a>:
</p>
        <pre class="c#" name="code">using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Linq;

namespace System.Data
{
    public static class DbConnectionExtensions
    {
        public static DataSet GetSchemaSet(this DbConnection connection)
        {
            DataSet result = new DataSet();

            DataTable collections = connection.GetSchema();

            List&lt;string&gt; availableCollectionNames = (from row in collections.AsEnumerable()
                                                     select row.Field&lt;string&gt;("CollectionName"))
                                                     .Distinct()
                                                     .ToList();

            foreach (string collectionName in availableCollectionNames)
            {
                try
                {
                    DataTable schemaTable = connection.GetSchema(collectionName);
                    result.Tables.Add(schemaTable);
                }
                catch { }
                // this is bad form and shouldn't be necessary but SqlClient seems to try to give Sql2008 metadata for 
                // Sql2005 connections which results in unneeded exceptions
            }

            return result;
        }
    }
}</pre>
        <p>
The other mechanism for getting metadata is the GetSchemaTable() method on the System.Data.IDataReader
interface, which provides some limited information on the metadata for the columns
that exist in a particular instance of IDataReader, typically from a call to DbCommand.ExecuteReader().
Again, GetSchemaTable(), as you might have guessed, returns a DataTable, this time
with structural information only relating to the columns of the IDataReader itself.
This, combined with DbDataReader.GetName(int) and DbDataReader.GetDataTypeName(int)
can give some pretty useful information for table and column structure returned from
a select statement. That being said, unless you’re reverse-engineering result sets
from stored procedures, you’ll likely find the DbConnection.GetSchema() functionality
much more effective.
</p>
        <p>
If you’re using the System.Data.OleDb provider, there’s the GetOleDbSchemaTable method
on the OleDbConnection class which provides its own metadata about the underlying
database. It works a little differently and takes a System.Guid value which refers
to the type of metadata being requested, all of which are static fields in the System.Data.OleDb.OleDbSchemaGuid
class.
</p>
        <pre class="c#" name="code">using System.Collections.Generic;
using System.Data.OleDb;
using System.Linq;
using System.Reflection;

namespace System.Data
{
    public static class OleDbConnectionExtensions
    {
        public static DataSet GetOleDbSchemaSet(this OleDbConnection connection)
        {
            DataSet result = new DataSet();
            List&lt;FieldInfo&gt; guidMembers = typeof(OleDbSchemaGuid).GetFields(BindingFlags.Static | BindingFlags.Public).ToList();

            foreach (FieldInfo field in guidMembers)
            {
                if (field.FieldType == typeof(Guid))
                {
                    Guid val = (Guid)field.GetValue(null);

                    try
                    {
                        DataTable schemaTable = connection.GetOleDbSchemaTable(val, new object[] { });
                        result.Tables.Add(schemaTable);
                    }
                    catch { } // unfortunately not all schema guids supported by all oledb connections necessarily
                }
            }

            return result;
        }
    }
}</pre>
        <h5>Oddities and Errata
</h5>
        <p>
Under .NET 3.5 (maybe SP1 only), if you execute .GetSchema() on a System.Data.SqlClient.SqlConnection
connected to a Sql Server 2005, you’ll notice there's a row indicating that the metadatacollection
called <em>StructuredTypeMembers</em> is available. However, this is Sql Server 2008-specific
and will throw an exception if you call .GetSchema(“StructuredTypeMembers”) on that
same Sql 2005 connection. Why Microsoft let it even be exposed during calls to .GetSchema()
on non-2008 connections, who knows. They already have a precedent for exposing Sql
2008-specific metadata depending on 2005/2008 server version as indicated <a href="http://msdn.microsoft.com/en-us/library/ms254969.aspx">here</a> so
it seems pretty stupid on their part. That’s the reason for the empty catch statement
in the code block above.
</p>
        <p>
Using <a href="http://dev.mysql.com/downloads/connector/net/5.2.html">MySql Connector
Net 5.2.5</a>, the schema collection of <em>Foreign Key Columns</em> is available
but not indicated by the resulting DataTable returned by MySqlConnection.GetSchema().
I notified <a href="http://www.reggieburnett.com/">Reggie Burnett</a>, who maintains
the Net Connector, and he says it’s been fixed, so I’d expect to see that in a future
release.
</p>
        <p>
Getting the structure of result sets from stored procedures or functions is even more
difficult than any of the basic table/column structure stuff I’ve mentioned. Using
Sql Server, you can use the <em>SET FMTONLY ON </em>statement before the stored procedure
call, and <em>SET FMTONLY OFF </em>afterwards, in order to get an empty result set
from which you can derive schema without executing against live data. However, to
do that in code, you’d have to derive their parameters using some other means like
GetSchema() and build a statement block with the FMTONLY lines surrounding the procedure
call. Oh, and none of this works if the stored procedure uses temporary tables to
return that result set. And again, it’s Sql Server specific. For MySql, the only way
I’ve figured out is to:
</p>
        <ol>
          <li>
Derive the parameter information using MySqlConnection.GetSchema(“Procedure Parameters”) 
</li>
          <li>
Construct a MySqlCommand with command text equal to the procedure name and CommandType
set to CommandType.StoredProcedure 
</li>
          <li>
Add phony parameters using the previously-derived information and set their values
to DBNull.Value. 
</li>
          <li>
Execute the command via ExecuteReader() 
</li>
          <li>
Reverse engineer the schema using GetName(int), GetDataTypeName(int) on the MySqlDataReader,
in tandem with GetSchemaTable(). Theoretically, if the information in the schema table
indicates the column came from a physical table, one could go to the source and look
at the values of MySqlConnection.GetSchema(“Columns”) for the source column definitions. 
</li>
        </ol>
        <p>
That’s likely how I’ll be doing it in the NDeavor providers where stored procedures
are supported like Oracle and Postgres. It’s less than ideal, but if you’re still
following this, you’d realize that’s my point! 
</p>
        <h5>Adding It Up
</h5>
        <p>
There’s a pattern to getting at your metadata and that pattern is it’s a pain in the
ass. I’m hoping NDeavor will provide an easy means of getting database schema out
of various platforms for the purposes of artifact-generation. But even so, I’m not
exactly planning on writing each NDeavor provider as its own one-off implementation
because there’s such inconsistency between metadata across platforms. I have a way
forward for a more lower-level means of getting at this stuff that solves a lot of
the cross-cutting discrepancies, and that will be in part 2.
</p>
        <img width="0" height="0" src="http://blog.invalidoperation.com/aggbug.ashx?id=5b20c588-314d-4ce2-b9f1-ed07b4fb7793" />
      </body>
      <title>Database Metadata in .Net Part 1 : The Problem</title>
      <guid isPermaLink="false">http://blog.invalidoperation.com/PermaLink,guid,5b20c588-314d-4ce2-b9f1-ed07b4fb7793.aspx</guid>
      <link>http://blog.invalidoperation.com/2009/02/16/DatabaseMetadataInNetPart1TheProblem.aspx</link>
      <pubDate>Mon, 16 Feb 2009 02:16:00 GMT</pubDate>
      <description>&lt;p&gt;
For most ORM or data layer utilities there is some component of code generation involved
and somewhere along the line retrieving some metadata about the underlying structure
of a database is usually involved. Seeing as it relates to &lt;a href="http://blog.invalidoperation.com/2008/12/11/CurrentProjectNDeavor.aspx"&gt;NDeavor&lt;/a&gt;,
I figured I’d write about the ins and outs of getting metadata when running close
to the database. Basically, there are a few basic ways to access database specific
metadata directly through .Net.
&lt;/p&gt;
&lt;h5&gt;Vendor-specific API.
&lt;/h5&gt;
&lt;p&gt;
I only know of one comprehensive API for this and it’s &lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=d09c1d60-a13c-4479-9b91-9e8b9d835cdc&amp;amp;displaylang=en"&gt;Sql
Management Objects (SMO)&lt;/a&gt; which is Sql-Server only. A tremendously useful API for
any Microsoft-dominated shops, though. Enumerating through basic structures like tables
and columns is incredibly easy, if a little slow. Getting the table name, column name,
and data type name of every column in every table in the &lt;a href="http://www.codeplex.com/ChinookDatabase"&gt;chinook&lt;/a&gt; database
might look like this:
&lt;/p&gt;
&lt;pre class="c#" name="code"&gt;public void PrintChinookTableColumns()
{
    ServerConnection sc = new ServerConnection(@&amp;quot;.\SQLEXPRESS&amp;quot;);
    sc.Connect();
    Server server = new Server(sc);
    Database chinookDb = server.Databases[&amp;quot;chinook&amp;quot;];
    server.SetDefaultInitFields(typeof(Table), &amp;quot;IsSystemObject&amp;quot;);
    foreach (Table table in chinookDb.Tables)
    {
        if (table.IsSystemObject)
            continue;

        string tableName = table.Name;

        foreach (Column col in table.Columns)
        {
            string columnName = col.Name;
            string dataTypeName = col.DataType.Name;

            Console.WriteLine(&amp;quot;{0} {1} {2}&amp;quot;, tableName, columnName, dataTypeName);
        }
    }
    sc.Disconnect();
}&lt;/pre&gt;
&lt;p&gt;
&amp;#160;
&lt;/p&gt;
&lt;h5&gt;Querying vendor-specific system tables. 
&lt;/h5&gt;
&lt;p&gt;
&lt;strong&gt;&lt;/strong&gt;Vendor lock-in at it’s finest, and typically unsupported at that.
Usefulness is dependent on what level of information is available and the amount of
time you’re willing to spend figuring out what the various columns and values mean.
Getting table, column, and data type names in a specific database in Sql Server Express
2005 might look like this:
&lt;/p&gt;
&lt;pre class="sql" name="code"&gt;use chinook
go

SELECT  T.name as TableName, 
        C.name as ColumnName,
        ST.name as DataType
FROM 
    sys.tables T 
    INNER JOIN sys.columns C on T.object_id = C.object_id
    INNER JOIN sys.systypes ST on C.system_type_id = ST.type&lt;/pre&gt;
&lt;h5&gt;&amp;#160;
&lt;/h5&gt;
&lt;h5&gt;Querying &lt;em&gt;standard&lt;/em&gt; metadata tables.
&lt;/h5&gt;
&lt;p&gt;
&lt;strong&gt;&lt;/strong&gt;Emphasis on ‘standard’, because there really is none. There is a
spec as part of the SQL standards that came along sometime around SQL92/SQL99 (not
sure) which dictates the INFORMATION_SCHEMA tables which store very basic metadata
about the tables, views, columns, procedures, functions, parameters, constraints,
etc, of a specific relational database. Support for these is relative to how much
the vendor cares about doing so. Sql Server and MySql both have pretty strong support
for these. But even then, the spec is very loose and while simple queries to say,
get all table names and column names, might be portable, more complex ones likely
won’t be. There’s other discrepancies as well, for instance the verbiage around ‘schema’
and ‘catalog’. In MySql terms &lt;em&gt;schema&lt;/em&gt; is analogous to a Sql Server &lt;em&gt;database&lt;/em&gt;,
and this translates down into their implementation of these metadata tables. Back
to the example of tables, columns, and data types in the chinook database:
&lt;/p&gt;
&lt;pre class="sql" name="code"&gt;Sql Server: 
use chinook 
go 

SELECT 
    T.TABLE_NAME as TableName,    
    C.COLUMN_NAME as ColumnName, 
    C.DATA_TYPE as DataType 
FROM 
    INFORMATION_SCHEMA.TABLES T 
    INNER JOIN INFORMATION_SCHEMA.COLUMNS C ON 
        T.TABLE_NAME = C.TABLE_NAME AND 
        T.TABLE_SCHEMA = C.TABLE_SCHEMA AND 
        T.TABLE_CATALOG = C.TABLE_CATALOG

 

MySql: 
SELECT 
    T.TABLE_NAME as TableName, 
    C.COLUMN_NAME as ColumnName, 
    C.DATA_TYPE as DataType 
FROM 
    INFORMATION_SCHEMA.TABLES T 
    INNER JOIN INFORMATION_SCHEMA.COLUMNS C ON 
        T.TABLE_NAME = C.TABLE_NAME AND 
        T.TABLE_SCHEMA = C.TABLE_SCHEMA 
WHERE T.TABLE_SCHEMA = 'chinook';&lt;/pre&gt;
&lt;h5&gt;&amp;#160;
&lt;/h5&gt;
&lt;h5&gt;Using the schema-related functionality in Ado.Net 2.0. 
&lt;/h5&gt;
&lt;p&gt;
Introduced in .Net 2.0, the DbConnection base class has a method with a few overloads
called GetSchema(). This is supposed to allow implementers of Ado.Net providers a
way to provide metadata about the underlying connected data store. Since it’s not
strongly typed, and consists of returning DataTables, it’s entirely up to the implementer
as far as what information is provided. Typically calling the parameter-less version
of GetSchema() would return a DataTable that describes what metadata is available,
indicated by a string column called something like &lt;em&gt;MetaDataCollection&lt;/em&gt; in
which you can pass to subsequent calls to GetSchema(string) to get that specific chunk
of metadata. There’s a decent write up of what’s available in the native Ado.Net providers
located &lt;a href="http://msdn.microsoft.com/en-us/library/kcax58fh.aspx"&gt;here&lt;/a&gt;.
Here’s an extension method to get all the metadata into one dataset for further manipulation,
which should work for the built-in Ado.Net providers, as well as MySql.Data.MysqlClient
using the latest &lt;a href="http://dev.mysql.com/downloads/connector/net/5.2.html"&gt;MySql
Net Connector&lt;/a&gt;:
&lt;/p&gt;
&lt;pre class="c#" name="code"&gt;using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Linq;

namespace System.Data
{
    public static class DbConnectionExtensions
    {
        public static DataSet GetSchemaSet(this DbConnection connection)
        {
            DataSet result = new DataSet();

            DataTable collections = connection.GetSchema();

            List&amp;lt;string&amp;gt; availableCollectionNames = (from row in collections.AsEnumerable()
                                                     select row.Field&amp;lt;string&amp;gt;(&amp;quot;CollectionName&amp;quot;))
                                                     .Distinct()
                                                     .ToList();

            foreach (string collectionName in availableCollectionNames)
            {
                try
                {
                    DataTable schemaTable = connection.GetSchema(collectionName);
                    result.Tables.Add(schemaTable);
                }
                catch { }
                // this is bad form and shouldn't be necessary but SqlClient seems to try to give Sql2008 metadata for 
                // Sql2005 connections which results in unneeded exceptions
            }

            return result;
        }
    }
}&lt;/pre&gt;
&lt;p&gt;
The other mechanism for getting metadata is the GetSchemaTable() method on the System.Data.IDataReader
interface, which provides some limited information on the metadata for the columns
that exist in a particular instance of IDataReader, typically from a call to DbCommand.ExecuteReader().
Again, GetSchemaTable(), as you might have guessed, returns a DataTable, this time
with structural information only relating to the columns of the IDataReader itself.
This, combined with DbDataReader.GetName(int) and DbDataReader.GetDataTypeName(int)
can give some pretty useful information for table and column structure returned from
a select statement. That being said, unless you’re reverse-engineering result sets
from stored procedures, you’ll likely find the DbConnection.GetSchema() functionality
much more effective.
&lt;/p&gt;
&lt;p&gt;
If you’re using the System.Data.OleDb provider, there’s the GetOleDbSchemaTable method
on the OleDbConnection class which provides its own metadata about the underlying
database. It works a little differently and takes a System.Guid value which refers
to the type of metadata being requested, all of which are static fields in the System.Data.OleDb.OleDbSchemaGuid
class.
&lt;/p&gt;
&lt;pre class="c#" name="code"&gt;using System.Collections.Generic;
using System.Data.OleDb;
using System.Linq;
using System.Reflection;

namespace System.Data
{
    public static class OleDbConnectionExtensions
    {
        public static DataSet GetOleDbSchemaSet(this OleDbConnection connection)
        {
            DataSet result = new DataSet();
            List&amp;lt;FieldInfo&amp;gt; guidMembers = typeof(OleDbSchemaGuid).GetFields(BindingFlags.Static | BindingFlags.Public).ToList();

            foreach (FieldInfo field in guidMembers)
            {
                if (field.FieldType == typeof(Guid))
                {
                    Guid val = (Guid)field.GetValue(null);

                    try
                    {
                        DataTable schemaTable = connection.GetOleDbSchemaTable(val, new object[] { });
                        result.Tables.Add(schemaTable);
                    }
                    catch { } // unfortunately not all schema guids supported by all oledb connections necessarily
                }
            }

            return result;
        }
    }
}&lt;/pre&gt;
&lt;h5&gt;Oddities and Errata
&lt;/h5&gt;
&lt;p&gt;
Under .NET 3.5 (maybe SP1 only), if you execute .GetSchema() on a System.Data.SqlClient.SqlConnection
connected to a Sql Server 2005, you’ll notice there's a row indicating that the metadatacollection
called &lt;em&gt;StructuredTypeMembers&lt;/em&gt; is available. However, this is Sql Server 2008-specific
and will throw an exception if you call .GetSchema(“StructuredTypeMembers”) on that
same Sql 2005 connection. Why Microsoft let it even be exposed during calls to .GetSchema()
on non-2008 connections, who knows. They already have a precedent for exposing Sql
2008-specific metadata depending on 2005/2008 server version as indicated &lt;a href="http://msdn.microsoft.com/en-us/library/ms254969.aspx"&gt;here&lt;/a&gt; so
it seems pretty stupid on their part. That’s the reason for the empty catch statement
in the code block above.
&lt;/p&gt;
&lt;p&gt;
Using &lt;a href="http://dev.mysql.com/downloads/connector/net/5.2.html"&gt;MySql Connector
Net 5.2.5&lt;/a&gt;, the schema collection of &lt;em&gt;Foreign Key Columns&lt;/em&gt; is available
but not indicated by the resulting DataTable returned by MySqlConnection.GetSchema().
I notified &lt;a href="http://www.reggieburnett.com/"&gt;Reggie Burnett&lt;/a&gt;, who maintains
the Net Connector, and he says it’s been fixed, so I’d expect to see that in a future
release.
&lt;/p&gt;
&lt;p&gt;
Getting the structure of result sets from stored procedures or functions is even more
difficult than any of the basic table/column structure stuff I’ve mentioned. Using
Sql Server, you can use the &lt;em&gt;SET FMTONLY ON &lt;/em&gt;statement before the stored procedure
call, and &lt;em&gt;SET FMTONLY OFF &lt;/em&gt;afterwards, in order to get an empty result set
from which you can derive schema without executing against live data. However, to
do that in code, you’d have to derive their parameters using some other means like
GetSchema() and build a statement block with the FMTONLY lines surrounding the procedure
call. Oh, and none of this works if the stored procedure uses temporary tables to
return that result set. And again, it’s Sql Server specific. For MySql, the only way
I’ve figured out is to:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Derive the parameter information using MySqlConnection.GetSchema(“Procedure Parameters”) 
&lt;/li&gt;
&lt;li&gt;
Construct a MySqlCommand with command text equal to the procedure name and CommandType
set to CommandType.StoredProcedure 
&lt;/li&gt;
&lt;li&gt;
Add phony parameters using the previously-derived information and set their values
to DBNull.Value. 
&lt;/li&gt;
&lt;li&gt;
Execute the command via ExecuteReader() 
&lt;/li&gt;
&lt;li&gt;
Reverse engineer the schema using GetName(int), GetDataTypeName(int) on the MySqlDataReader,
in tandem with GetSchemaTable(). Theoretically, if the information in the schema table
indicates the column came from a physical table, one could go to the source and look
at the values of MySqlConnection.GetSchema(“Columns”) for the source column definitions. 
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
That’s likely how I’ll be doing it in the NDeavor providers where stored procedures
are supported like Oracle and Postgres. It’s less than ideal, but if you’re still
following this, you’d realize that’s my point! 
&lt;/p&gt;
&lt;h5&gt;Adding It Up
&lt;/h5&gt;
&lt;p&gt;
There’s a pattern to getting at your metadata and that pattern is it’s a pain in the
ass. I’m hoping NDeavor will provide an easy means of getting database schema out
of various platforms for the purposes of artifact-generation. But even so, I’m not
exactly planning on writing each NDeavor provider as its own one-off implementation
because there’s such inconsistency between metadata across platforms. I have a way
forward for a more lower-level means of getting at this stuff that solves a lot of
the cross-cutting discrepancies, and that will be in part 2.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.invalidoperation.com/aggbug.ashx?id=5b20c588-314d-4ce2-b9f1-ed07b4fb7793" /&gt;</description>
      <comments>http://blog.invalidoperation.com/CommentView,guid,5b20c588-314d-4ce2-b9f1-ed07b4fb7793.aspx</comments>
      <category>Ado.Net</category>
      <category>database</category>
      <category>metadata</category>
      <category>MySql</category>
      <category>NDeavor</category>
      <category>Sql Server</category>
    </item>
    <item>
      <trackback:ping>http://blog.invalidoperation.com/Trackback.aspx?guid=a9d0b8d6-b9f8-4aeb-8633-58b5fcad9525</trackback:ping>
      <pingback:server>http://blog.invalidoperation.com/pingback.aspx</pingback:server>
      <pingback:target>http://blog.invalidoperation.com/PermaLink,guid,a9d0b8d6-b9f8-4aeb-8633-58b5fcad9525.aspx</pingback:target>
      <dc:creator>Ray</dc:creator>
      <wfw:comment>http://blog.invalidoperation.com/CommentView,guid,a9d0b8d6-b9f8-4aeb-8633-58b5fcad9525.aspx</wfw:comment>
      <wfw:commentRss>http://blog.invalidoperation.com/SyndicationService.asmx/GetEntryCommentsRss?guid=a9d0b8d6-b9f8-4aeb-8633-58b5fcad9525</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
NDeavor is a hobby project of mine that I’ve been working on for a couple months now
on and off. It’s basically a way for me to explore the things I’m interested in but
don’t get to explore in my day job, specifically the latest and greatest from Net
like LINQ, extensibility patterns like MEF or System.AddIn, working with database
metadata, dependency injection, and code generation. It’s a set of libraries and code
that puts a relational database schema in a straight forward object model for the
purposes of generating some other artifacts. Boring, I know. Been done before, I know.
But never done simply enough (and free enough) to where I could say that my take is
unnecessary. Extensibility is currently being provided using the <a href="http://www.codeplex.com/mef">Managed
Extensibility Framework</a> (MEF) in which I’ve defined some <em>extremely</em> simple
contracts for a provider kind of model for support of all the different database platforms
out there. I started with System.AddIn then switched to MEF, but that’s a post in
and of it’s own.
</p>
        <h4>Object Model
</h4>
        <p>
These are the interfaces, they’re purposely simple, and yet to be finalized:
</p>
        <p>
          <a href="http://blog.invalidoperation.com/content/binary/WindowsLiveWriter/CurrentProjectNDeavor_11D9/NDeavor_ObjectModel_4.png">
            <img title="NDeavor_ObjectModel" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="342" alt="NDeavor_ObjectModel" src="http://blog.invalidoperation.com/content/binary/WindowsLiveWriter/CurrentProjectNDeavor_11D9/NDeavor_ObjectModel_thumb_1.png" width="794" border="0" />
          </a>
        </p>
        <p>
The actual contracts aren’t defined on these, as the interfaces are mostly for the
purposes of mocking and testing. That, and they are left over from when everything <em>had</em> to
be a contract when I was using System.AddIn. Thinking about ditching them in favor
of concrete classes.
</p>
        <h6>
        </h6>
        <h4>That’s great, what does it do?
</h4>
        <p>
Well on the surface, it’s just a library where any external developer can implement
these two interfaces to support a specific database platform. Of course, I’ll be writing
providers for the major platforms as that’s the part I”m most interested in.
</p>
        <p>
          <a href="http://blog.invalidoperation.com/content/binary/WindowsLiveWriter/CurrentProjectNDeavor_11D9/NDeavor_ProviderInterfaces_4.png">
            <img title="NDeavor_ProviderInterfaces" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="135" alt="NDeavor_ProviderInterfaces" src="http://blog.invalidoperation.com/content/binary/WindowsLiveWriter/CurrentProjectNDeavor_11D9/NDeavor_ProviderInterfaces_thumb_1.png" width="458" border="0" />
          </a>
        </p>
        <p>
Each <strong>ISchemaProvider, </strong>who’s <strong>GetSchema</strong> method returns
an object that implements <strong>IDatabase</strong>, can be associated to one <strong>IDataTypeProvider, </strong>which
is used to get more common <strong>System.Data.DbType</strong> and <strong>System.Type</strong> mappings
from vendor-specific data types. I <em>did </em>say it was simple.
</p>
        <p>
Once you have a provider for NDeavor that supports your database platform of choice,
you’ll be able to put it in some directory somewhere and be able to call some code
in the <strong>NDeavor.Core</strong> assembly which will instantiate the plugin, provided
you know it’s associated plugin name. After that, you can do anything with the object
model that you can do programmatically: use CodeDOM to generate C# or VB code, reverse-engieer
SQL scripts, whatever.
</p>
        <p>
The current example of putting NDeavor to work that I’ll be providing is invoking
NDeavor via <a href="http://www.hanselman.com/blog/T4TextTemplateTransformationToolkitCodeGenerationBestKeptVisualStudioSecret.aspx">T4
Templates</a>. I wrote a custom <a href="http://msdn.microsoft.com/en-us/library/bb126315.aspx">T4
Directive Processor</a> which allows you to put a bit of angle bracket text in a T4
template which adds a couple properties to the generated template-class, allowing
you to manipulate the model in the ‘code-behind’ of the template itself. For example,
this bit of T4 template text:
</p>
        <pre class="c#" name="code">&lt;#@ template debug="True" language="C#v3.5" #&gt;
&lt;#@ output extension="cs" #&gt;
&lt;#@ assembly name="System.Data" #&gt;
&lt;#@ assembly name="C:\Program Files\SubSonic\SubSonic 2.1 Final\SubSonic\SubSonic.dll" #&gt;
&lt;#@ import namespace="System.Linq" #&gt;
&lt;#@ import namespace="System.Diagnostics" #&gt;
&lt;#@ import namespace="System.Data" #&gt;
&lt;#@ import namespace="SubSonic" #&gt;
&lt;#@ import namespace="System.Collections.Generic" #&gt;
&lt;#@ include file="TemplateInclude.tt" #&gt;
&lt;#@ DataModel Processor="DataModelDirectiveProcessor" Database="chinook" Name="Chinook" ConnectionStringName="Chinook_MySql" SchemaProvider="NDeavor.SchemaProviders.MySql" #&gt;
&lt;#  IDatabase db = this.ChinookDataModel; 
    IDataTypeProvider prov = this.ChinookDataTypeProvider; #&gt;
using System;
using System.Collections.Generic;

namespace Model
{
&lt;#foreach(ITable table in db.Tables) {#&gt;
    public class &lt;#=GetClassName(table)#&gt;
    {        
&lt;#foreach(IColumn col in table.Columns) {#&gt;
        public &lt;#=prov.GetSystemType(col).FullName#&gt; &lt;#=GetSingularPropertyName(col)#&gt; { get; set; } 
&lt;#}#&gt;
    }
    
&lt;#}#&gt;
}</pre>
        <p>
Generates a bunch of code like this:
</p>
        <pre class="c#" name="code">    public class Customer
    {        
        public System.Int32 CustomerId { get; set; } 
        public System.String FirstName { get; set; } 
        public System.String LastName { get; set; } 
        public System.String Company { get; set; } 
        public System.String Address { get; set; } 
        public System.String City { get; set; } 
        public System.String State { get; set; } 
        public System.String Country { get; set; } 
        public System.String PostalCode { get; set; } 
        public System.String Phone { get; set; } 
        public System.String Fax { get; set; } 
        public System.String Email { get; set; } 
    }
    
    public class Employee
    {        
        public System.Int32 EmployeeId { get; set; } 
        public System.String LastName { get; set; } 
        public System.String FirstName { get; set; } 
        public System.String Title { get; set; } 
        public System.Int32 ReportsTo { get; set; } 
        public System.DateTime BirthDate { get; set; } 
        public System.DateTime HireDate { get; set; } 
        public System.String Address { get; set; } 
        public System.String City { get; set; } 
        public System.String State { get; set; } 
        public System.String Country { get; set; } 
        public System.String PostalCode { get; set; } 
        public System.String Phone { get; set; } 
        public System.String Fax { get; set; } 
        public System.String Email { get; set; } 
    }</pre>
        <p>
Now that’s what I’m talking about. No querying system tables, no custom vendor-specific
api, it’s all done for you in that bit of angle brackets. Booyah. Oh, and I’m using <a href="http://www.codeplex.com/subsonic">SubSonic</a> solely
for the Inflector class to singularlize class names, it’s totally not required for
NDeavor. I may provide my own ‘extra’s like that with the T4 functionality, not sure.
</p>
        <h4>Tentative To-Do List
</h4>
        <ul>
          <li>
Get object model to more polished and developer-friendly state. Includes ditching
some of the POCO-ness in favor of read-only collections backed by specific Add/Remove
methods, or custom collections all together, I haven’t nailed that down yet. 
</li>
          <li>
Get 2 providers written. I’m writing the MySql provider in tandem, first as a break
from Sql Server which I use daily, and second as a way to get a view of how another
platform does things (you <em>flag</em> an integer column to make it unsigned? <em>seriously?</em>),
and how those things translate into a generalized framework like this. 
</li>
          <li>
Figure out configuration of standard plugin directory and how to implement subdirectory
watching using MEF. 
</li>
          <li>
Test. Test. Test. 
</li>
          <li>
Blog about the ways to access metadata in various database platforms. (MySql 5.x has
good, yet incomplete, support of the INFORMATION_SCHEMA ‘standard’, yet I’m using
the .GetSchema() methods on the MySqlDataConnection class, via <a href="http://dev.mysql.com/downloads/connector/net/5.2.html">MySql
Net Connector 5.2</a>. ) 
</li>
          <li>
Publish to CodePlex when all’s good. (License?) 
</li>
        </ul>
        <p>
That’s it for now. More to come!
</p>
        <img width="0" height="0" src="http://blog.invalidoperation.com/aggbug.ashx?id=a9d0b8d6-b9f8-4aeb-8633-58b5fcad9525" />
      </body>
      <title>Current Project: NDeavor</title>
      <guid isPermaLink="false">http://blog.invalidoperation.com/PermaLink,guid,a9d0b8d6-b9f8-4aeb-8633-58b5fcad9525.aspx</guid>
      <link>http://blog.invalidoperation.com/2008/12/11/CurrentProjectNDeavor.aspx</link>
      <pubDate>Thu, 11 Dec 2008 06:54:00 GMT</pubDate>
      <description>&lt;p&gt;
NDeavor is a hobby project of mine that I’ve been working on for a couple months now
on and off. It’s basically a way for me to explore the things I’m interested in but
don’t get to explore in my day job, specifically the latest and greatest from Net
like LINQ, extensibility patterns like MEF or System.AddIn, working with database
metadata, dependency injection, and code generation. It’s a set of libraries and code
that puts a relational database schema in a straight forward object model for the
purposes of generating some other artifacts. Boring, I know. Been done before, I know.
But never done simply enough (and free enough) to where I could say that my take is
unnecessary. Extensibility is currently being provided using the &lt;a href="http://www.codeplex.com/mef"&gt;Managed
Extensibility Framework&lt;/a&gt; (MEF) in which I’ve defined some &lt;em&gt;extremely&lt;/em&gt; simple
contracts for a provider kind of model for support of all the different database platforms
out there. I started with System.AddIn then switched to MEF, but that’s a post in
and of it’s own.
&lt;/p&gt;
&lt;h4&gt;Object Model
&lt;/h4&gt;
&lt;p&gt;
These are the interfaces, they’re purposely simple, and yet to be finalized:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.invalidoperation.com/content/binary/WindowsLiveWriter/CurrentProjectNDeavor_11D9/NDeavor_ObjectModel_4.png"&gt;&lt;img title="NDeavor_ObjectModel" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="342" alt="NDeavor_ObjectModel" src="http://blog.invalidoperation.com/content/binary/WindowsLiveWriter/CurrentProjectNDeavor_11D9/NDeavor_ObjectModel_thumb_1.png" width="794" border="0" /&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
The actual contracts aren’t defined on these, as the interfaces are mostly for the
purposes of mocking and testing. That, and they are left over from when everything &lt;em&gt;had&lt;/em&gt; to
be a contract when I was using System.AddIn. Thinking about ditching them in favor
of concrete classes.
&lt;/p&gt;
&lt;h6&gt;
&lt;/h6&gt;
&lt;h4&gt;That’s great, what does it do?
&lt;/h4&gt;
&lt;p&gt;
Well on the surface, it’s just a library where any external developer can implement
these two interfaces to support a specific database platform. Of course, I’ll be writing
providers for the major platforms as that’s the part I”m most interested in.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.invalidoperation.com/content/binary/WindowsLiveWriter/CurrentProjectNDeavor_11D9/NDeavor_ProviderInterfaces_4.png"&gt;&lt;img title="NDeavor_ProviderInterfaces" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="135" alt="NDeavor_ProviderInterfaces" src="http://blog.invalidoperation.com/content/binary/WindowsLiveWriter/CurrentProjectNDeavor_11D9/NDeavor_ProviderInterfaces_thumb_1.png" width="458" border="0" /&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
Each &lt;strong&gt;ISchemaProvider, &lt;/strong&gt;who’s &lt;strong&gt;GetSchema&lt;/strong&gt; method returns
an object that implements &lt;strong&gt;IDatabase&lt;/strong&gt;, can be associated to one &lt;strong&gt;IDataTypeProvider, &lt;/strong&gt;which
is used to get more common &lt;strong&gt;System.Data.DbType&lt;/strong&gt; and &lt;strong&gt;System.Type&lt;/strong&gt; mappings
from vendor-specific data types. I &lt;em&gt;did &lt;/em&gt;say it was simple.
&lt;/p&gt;
&lt;p&gt;
Once you have a provider for NDeavor that supports your database platform of choice,
you’ll be able to put it in some directory somewhere and be able to call some code
in the &lt;strong&gt;NDeavor.Core&lt;/strong&gt; assembly which will instantiate the plugin, provided
you know it’s associated plugin name. After that, you can do anything with the object
model that you can do programmatically: use CodeDOM to generate C# or VB code, reverse-engieer
SQL scripts, whatever.
&lt;/p&gt;
&lt;p&gt;
The current example of putting NDeavor to work that I’ll be providing is invoking
NDeavor via &lt;a href="http://www.hanselman.com/blog/T4TextTemplateTransformationToolkitCodeGenerationBestKeptVisualStudioSecret.aspx"&gt;T4
Templates&lt;/a&gt;. I wrote a custom &lt;a href="http://msdn.microsoft.com/en-us/library/bb126315.aspx"&gt;T4
Directive Processor&lt;/a&gt; which allows you to put a bit of angle bracket text in a T4
template which adds a couple properties to the generated template-class, allowing
you to manipulate the model in the ‘code-behind’ of the template itself. For example,
this bit of T4 template text:
&lt;/p&gt;
&lt;pre class="c#" name="code"&gt;&amp;lt;#@ template debug=&amp;quot;True&amp;quot; language=&amp;quot;C#v3.5&amp;quot; #&amp;gt;
&amp;lt;#@ output extension=&amp;quot;cs&amp;quot; #&amp;gt;
&amp;lt;#@ assembly name=&amp;quot;System.Data&amp;quot; #&amp;gt;
&amp;lt;#@ assembly name=&amp;quot;C:\Program Files\SubSonic\SubSonic 2.1 Final\SubSonic\SubSonic.dll&amp;quot; #&amp;gt;
&amp;lt;#@ import namespace=&amp;quot;System.Linq&amp;quot; #&amp;gt;
&amp;lt;#@ import namespace=&amp;quot;System.Diagnostics&amp;quot; #&amp;gt;
&amp;lt;#@ import namespace=&amp;quot;System.Data&amp;quot; #&amp;gt;
&amp;lt;#@ import namespace=&amp;quot;SubSonic&amp;quot; #&amp;gt;
&amp;lt;#@ import namespace=&amp;quot;System.Collections.Generic&amp;quot; #&amp;gt;
&amp;lt;#@ include file=&amp;quot;TemplateInclude.tt&amp;quot; #&amp;gt;
&amp;lt;#@ DataModel Processor=&amp;quot;DataModelDirectiveProcessor&amp;quot; Database=&amp;quot;chinook&amp;quot; Name=&amp;quot;Chinook&amp;quot; ConnectionStringName=&amp;quot;Chinook_MySql&amp;quot; SchemaProvider=&amp;quot;NDeavor.SchemaProviders.MySql&amp;quot; #&amp;gt;
&amp;lt;#  IDatabase db = this.ChinookDataModel; 
    IDataTypeProvider prov = this.ChinookDataTypeProvider; #&amp;gt;
using System;
using System.Collections.Generic;

namespace Model
{
&amp;lt;#foreach(ITable table in db.Tables) {#&amp;gt;
    public class &amp;lt;#=GetClassName(table)#&amp;gt;
    {        
&amp;lt;#foreach(IColumn col in table.Columns) {#&amp;gt;
        public &amp;lt;#=prov.GetSystemType(col).FullName#&amp;gt; &amp;lt;#=GetSingularPropertyName(col)#&amp;gt; { get; set; } 
&amp;lt;#}#&amp;gt;
    }
    
&amp;lt;#}#&amp;gt;
}&lt;/pre&gt;
&lt;p&gt;
Generates a bunch of code like this:
&lt;/p&gt;
&lt;pre class="c#" name="code"&gt;    public class Customer
    {        
        public System.Int32 CustomerId { get; set; } 
        public System.String FirstName { get; set; } 
        public System.String LastName { get; set; } 
        public System.String Company { get; set; } 
        public System.String Address { get; set; } 
        public System.String City { get; set; } 
        public System.String State { get; set; } 
        public System.String Country { get; set; } 
        public System.String PostalCode { get; set; } 
        public System.String Phone { get; set; } 
        public System.String Fax { get; set; } 
        public System.String Email { get; set; } 
    }
    
    public class Employee
    {        
        public System.Int32 EmployeeId { get; set; } 
        public System.String LastName { get; set; } 
        public System.String FirstName { get; set; } 
        public System.String Title { get; set; } 
        public System.Int32 ReportsTo { get; set; } 
        public System.DateTime BirthDate { get; set; } 
        public System.DateTime HireDate { get; set; } 
        public System.String Address { get; set; } 
        public System.String City { get; set; } 
        public System.String State { get; set; } 
        public System.String Country { get; set; } 
        public System.String PostalCode { get; set; } 
        public System.String Phone { get; set; } 
        public System.String Fax { get; set; } 
        public System.String Email { get; set; } 
    }&lt;/pre&gt;
&lt;p&gt;
Now that’s what I’m talking about. No querying system tables, no custom vendor-specific
api, it’s all done for you in that bit of angle brackets. Booyah. Oh, and I’m using &lt;a href="http://www.codeplex.com/subsonic"&gt;SubSonic&lt;/a&gt; solely
for the Inflector class to singularlize class names, it’s totally not required for
NDeavor. I may provide my own ‘extra’s like that with the T4 functionality, not sure.
&lt;/p&gt;
&lt;h4&gt;Tentative To-Do List
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
Get object model to more polished and developer-friendly state. Includes ditching
some of the POCO-ness in favor of read-only collections backed by specific Add/Remove
methods, or custom collections all together, I haven’t nailed that down yet. 
&lt;/li&gt;
&lt;li&gt;
Get 2 providers written. I’m writing the MySql provider in tandem, first as a break
from Sql Server which I use daily, and second as a way to get a view of how another
platform does things (you &lt;em&gt;flag&lt;/em&gt; an integer column to make it unsigned? &lt;em&gt;seriously?&lt;/em&gt;),
and how those things translate into a generalized framework like this. 
&lt;/li&gt;
&lt;li&gt;
Figure out configuration of standard plugin directory and how to implement subdirectory
watching using MEF. 
&lt;/li&gt;
&lt;li&gt;
Test. Test. Test. 
&lt;/li&gt;
&lt;li&gt;
Blog about the ways to access metadata in various database platforms. (MySql 5.x has
good, yet incomplete, support of the INFORMATION_SCHEMA ‘standard’, yet I’m using
the .GetSchema() methods on the MySqlDataConnection class, via &lt;a href="http://dev.mysql.com/downloads/connector/net/5.2.html"&gt;MySql
Net Connector 5.2&lt;/a&gt;. ) 
&lt;/li&gt;
&lt;li&gt;
Publish to CodePlex when all’s good. (License?) 
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
That’s it for now. More to come!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.invalidoperation.com/aggbug.ashx?id=a9d0b8d6-b9f8-4aeb-8633-58b5fcad9525" /&gt;</description>
      <comments>http://blog.invalidoperation.com/CommentView,guid,a9d0b8d6-b9f8-4aeb-8633-58b5fcad9525.aspx</comments>
      <category>NDeavor</category>
    </item>
    <item>
      <trackback:ping>http://blog.invalidoperation.com/Trackback.aspx?guid=9593a0b8-8e5b-49d6-8841-77d4194e80a7</trackback:ping>
      <pingback:server>http://blog.invalidoperation.com/pingback.aspx</pingback:server>
      <pingback:target>http://blog.invalidoperation.com/PermaLink,guid,9593a0b8-8e5b-49d6-8841-77d4194e80a7.aspx</pingback:target>
      <dc:creator>Ray</dc:creator>
      <wfw:comment>http://blog.invalidoperation.com/CommentView,guid,9593a0b8-8e5b-49d6-8841-77d4194e80a7.aspx</wfw:comment>
      <wfw:commentRss>http://blog.invalidoperation.com/SyndicationService.asmx/GetEntryCommentsRss?guid=9593a0b8-8e5b-49d6-8841-77d4194e80a7</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
So this is my blog. I can’t believe this domain was available. This will be another
nerdy developer/.NET blog like the billions others.
</p>
        <p>
TODO:
</p>
        <p>
- <strike>Customize dasblog theme</strike></p>
        <p>
- <strike>Get SyntaxHighlighter all hooked up</strike></p>
        <p>
- Produce content
</p>
        <p>
- <strike>Find better hosting. Godaddy is awful. Excuse for a vps, maybe?</strike></p>
        <pre class="c#" name="code">public class Foo
{
    public Foo()
    {
        Console.WriteLine("what?");
    }
}</pre>
test<img width="0" height="0" src="http://blog.invalidoperation.com/aggbug.ashx?id=9593a0b8-8e5b-49d6-8841-77d4194e80a7" /></body>
      <title>hello blog</title>
      <guid isPermaLink="false">http://blog.invalidoperation.com/PermaLink,guid,9593a0b8-8e5b-49d6-8841-77d4194e80a7.aspx</guid>
      <link>http://blog.invalidoperation.com/2008/12/09/helloBlog.aspx</link>
      <pubDate>Tue, 09 Dec 2008 12:30:00 GMT</pubDate>
      <description>&lt;p&gt;
So this is my blog. I can’t believe this domain was available. This will be another
nerdy developer/.NET blog like the billions others.
&lt;/p&gt;
&lt;p&gt;
TODO:
&lt;/p&gt;
&lt;p&gt;
- &lt;strike&gt;Customize dasblog theme&lt;/strike&gt;
&lt;/p&gt;
&lt;p&gt;
- &lt;strike&gt;Get SyntaxHighlighter all hooked up&lt;/strike&gt; 
&lt;/p&gt;
&lt;p&gt;
- Produce content
&lt;/p&gt;
&lt;p&gt;
- &lt;strike&gt;Find better hosting. Godaddy is awful. Excuse for a vps, maybe?&lt;/strike&gt;
&lt;/p&gt;
&lt;pre class="c#" name="code"&gt;public class Foo
{
    public Foo()
    {
        Console.WriteLine("what?");
    }
}&lt;/pre&gt;
test&lt;img width="0" height="0" src="http://blog.invalidoperation.com/aggbug.ashx?id=9593a0b8-8e5b-49d6-8841-77d4194e80a7" /&gt;</description>
      <comments>http://blog.invalidoperation.com/CommentView,guid,9593a0b8-8e5b-49d6-8841-77d4194e80a7.aspx</comments>
      <category>meta</category>
    </item>
  </channel>
</rss>