<?xml version="1.0" encoding="utf-8"?>
<feed xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xml:lang="en-us" xmlns="http://www.w3.org/2005/Atom">
  <title>Extemporaneous Mumblings</title>
  <link rel="alternate" type="text/html" href="http://dunnry.com/blog/" />
  <link rel="self" href="http://dunnry.com/blog/SyndicationService.asmx/GetAtom" />
  <icon>favicon.ico</icon>
  <updated>2008-07-02T19:43:26.5591204-04:00</updated>
  <author>
    <name>Ryan Dunn</name>
  </author>
  <subtitle>... a blog by Ryan Dunn</subtitle>
  <id>http://dunnry.com/blog/</id>
  <generator uri="http://www.dasblog.net" version="2.0.7180.0">DasBlog</generator>
  <entry>
    <title>Working with Objects in SSDS Part 3</title>
    <link rel="alternate" type="text/html" href="http://dunnry.com/blog/WorkingWithObjectsInSSDSPart3.aspx" />
    <id>http://dunnry.com/blog/PermaLink,guid,b37072b9-1fe8-4785-9df3-00861ab346f7.aspx</id>
    <published>2008-07-02T19:43:26.5591204-04:00</published>
    <updated>2008-07-02T19:43:26.5591204-04:00</updated>
    <category term=".NET" label=".NET" scheme="http://dunnry.com/blog/CategoryView,category,.NET.aspx" />
    <category term="Cloud Services" label="Cloud Services" scheme="http://dunnry.com/blog/CategoryView,category,Cloud%2BServices.aspx" />
    <category term="SSDS" label="SSDS" scheme="http://dunnry.com/blog/CategoryView,category,SSDS.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
Here is my last installment in this series of working with objects in SQL Server Data
Services.  For background, readers should read the following:
</p>
        <p>
          <a href="http://dunnry.com/blog/SerializationInSSDS.aspx">Serialization in SSDS</a>
        </p>
        <p>
          <a href="http://dunnry.com/blog/WorkingWithObjectsInSSDSPart1.aspx">Working with Objects
in SSDS Part 1</a>
        </p>
        <p>
          <a href="http://dunnry.com/blog/WorkingWithObjectsInSSDSPart2.aspx">Working with Objects
in SSDS Part 2</a>
        </p>
        <p>
Last time, we concluded with a class called <strong>SsdsEntity&lt;T&gt;</strong> that
became an all-purpose wrapper or veneer around our CLR objects.  This made it
simple to take our existing classes and serialize them as entities in SSDS.
</p>
        <p>
In this post, I want to discuss how the querying in the REST library works. 
First a simple example:
</p>
        <div>
          <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">var ctx = <span style="color: #0000ff">new</span> SsdsContext( <span style="color: #006080">"authority=http://dunnry.data.beta.mssds.com/v1/;username=dunnry;password=secret"</span> );
var container = ctx.OpenContainer(<span style="color: #006080">"foo"</span>); var
foo = <span style="color: #0000ff">new</span> Foo { IsPublic = <span style="color: #0000ff">false</span>,
Name = <span style="color: #006080">"MyFoo"</span>, Size = 12 }; <span style="color: #008000">//insert
it with unique id guid string</span> container.Insert(foo, Guid.NewGuid().ToString()); <span style="color: #008000">//now
query for it</span> var results = container.Query&lt;Foo&gt;(e =&gt; e.Entity.IsPublic
== <span style="color: #0000ff">false</span> &amp;&amp; e.Entity.Size &gt; 2); <span style="color: #008000">//Query&lt;T&gt;
returns IEnumerable&lt;SsdsEntity&lt;T&gt;&gt;, so foreach over it</span><span style="color: #0000ff">foreach</span> (var
item <span style="color: #0000ff">in</span> results) { Console.WriteLine(item.Entity.Name);
}</pre>
        </div>
        <p>
I glossed over it in my previous posts with this library, but I have a class called <strong>SsdsContext</strong> that
acts as my credential store and factory to create <strong>SsdsContainer</strong> objects
where I perform my operations.  Here, I have opened a container called 'foo',
which would relate to the URI (<a href="http://dunnry.data.beta.mssds.com/v1/foo">http://dunnry.data.beta.mssds.com/v1/foo</a>)
according to the authority name I passed on the <strong>SsdsContext</strong> constructor
arguments.
</p>
        <p>
I created an instance of my <strong>Foo</strong> class (see <a href="http://dunnry.com/blog/WorkingWithObjectsInSSDSPart1.aspx">this
post</a> if you want to see what a <strong>Foo</strong> looks like) and inserted it. 
We know that under the covers we have an <strong>XmlSerializer</strong> doing the
work to serialize that to the proper POX wire format.  So far, so good. 
Now, I want to retrieve that same entity back from SSDS. The key line here is the
table.Query&lt;T&gt;() call.  It accepts a <strong>Expression&lt;Func&lt;SsdsEntity&lt;T&gt;,
bool&gt;&gt;</strong> argument that represents a strongly typed query.
</p>
        <p>
For the uninitiated, the <strong>Expression&lt;TDelegate&gt;</strong> is a way to
represent lambda expressions in an abstract syntax tree.  We can think of them
as a way to model what the expression does without generating the bits of code necessary
to actually do it.  We can inspect the <strong>Expression</strong> and create
new ones based on it until finally we can call Compile and actually convert the representation
of the lambda into something that can execute.
</p>
        <p>
The <strong>Func&lt;SsdsEntity&lt;T&gt;, bool&gt;</strong> represents a delegate that
accepts a <strong>SsdsEntity&lt;T&gt;</strong> as an argument and returns a boolean. 
This effectively represents the WHERE clause in the SSDS LINQ query syntax. 
Since <strong>SsdsEntity&lt;T&gt;</strong> contains an actual type T in the <strong>Entity</strong> property,
you can query directly against it in a strongly typed fashion!
</p>
        <p>
What about those flexible properties that I added to support flexible attributes outside
of our T?  I mentioned that I wanted to keep the <strong>PropertyBucket</strong> (a <strong>Dictionary&lt;string,
object&gt;</strong>) property public for querying.  In order to use the flexible
properties that you add, you simply use it in a weakly typed manner:
</p>
        <div>
          <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">var results = container.Query&lt;Foo&gt;(e =&gt; e.PropertyBucket[<span style="color: #006080">"MyFlexProp"</span>]
&gt; 10);</pre>
        </div>
        <p>
As you can see, any boolean expression that you can think of in the string-based SSDS
LINQ query syntax can now be expressed in a strongly-typed manner using the <strong>Func&lt;SsdsEntity&lt;T&gt;,
bool&gt;</strong> lambda syntax.
</p>
        <h3>How it works
</h3>
        <p>
Since I have the expression tree of what your query looks like in strongly-typed terms,
it is a simple matter to take that and convert it to the SSDS LINQ query syntax that
looks like "from e in entities where [....] select e" that is appended to the query
string in the REST interface.  I should say it is a simple matter because <a href="http://blogs.msdn.com/mattwar/archive/2007/07/30/linq-building-an-iqueryable-provider-part-i.aspx">Matt
Warren</a> did a lot of the heavy lifting for us and provided the abstract expression
visitor (<strong>ExpressionVisitor</strong>) as well as the expression visitor that
partially evaluates the tree to evaluate constants (<strong>SubTreeEvaluator</strong>). 
This last part is important because it allows us to write this:
</p>
        <div>
          <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
            <span style="color: #0000ff">int</span> i
= 10; <span style="color: #0000ff">string</span> name = <span style="color: #006080">"MyFoo"</span>;
var results = container.Query&lt;Foo&gt;(e =&gt; e.Entity.Name == name &amp;&amp;
e.Entity.Size &gt; i);</pre>
        </div>
        <p>
Without the partial tree evaluation, you would not be able to express the right hand
side of the equation.  All I had to do was implement an expression visitor that
correctly evaluated the lambda expression and converted it to the LINQ syntax that
SSDS expects (<strong>SsdsExpressionVisitor</strong>).  It would be a trivial
matter to actually implement the <strong>IQueryProvider</strong> and <strong>IQueryable</strong> interfaces
to make the whole thing work inside LINQ to Objects.
</p>
        <p>
Originally, I did supply the <strong>IQueryProvider</strong> for this implementation
but after consideration I have decided that using methods from the <strong>SsdsContainer</strong> class
instead of the standard LINQ syntax is the best way to proceed.  Mainly, this
has to do with the fact that I want to make it more explicit to the developer what
will happen under the covers rather than using the standard <strong>Where()</strong> extension
method.
</p>
        <h3>Querying data
</h3>
        <p>
The main interaction to return data is via the <strong>Query&lt;T&gt;</strong> method. 
This method is smart enough to add the Kind into the query for you based on the T
supplied.  So, if you write something like:
</p>
        <div>
          <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">var results = container.Query&lt;Foo&gt;(e =&gt; e.Entity.Size &gt; 2);</pre>
        </div>
        <p>
This is actually translated to "<em>from e in entities where e["Size"] &gt; 2 &amp;&amp;
e.Kind == "Foo" select e</em>".  The addition of the kind is important because
we want to limit the results as much as possible.  If there happened to be many
kinds in the container that had the flexible property "Size", it would actually return
those as well in the wire response.
</p>
        <p>
Of course, what about if you want that to happen?  What if you want to return
other kinds that have the "Size" property?  To do this, I have introduced a class
called <strong>SsdsEntityBucket</strong>.  It is exactly what it sounds like. 
To use it, you simply specify a query that uses additional types with either the <strong>Query&lt;T,U,V&gt;</strong> or <strong>Query&lt;T,U&gt;</strong> methods. 
Here is an example:
</p>
        <div>
          <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">var foo = <span style="color: #0000ff">new</span> Foo
{ IsPublic = <span style="color: #0000ff">true</span>, MyCheese = <span style="color: #0000ff">new</span> Cheese
{ LastModified = DateTime.Now, Name = <span style="color: #006080">"MyCheese"</span> },
Name = <span style="color: #006080">"FooMaster"</span>, Size = 10 }; container.Insert(foo,
foo.Name); container.Insert(foo.MyCheese, foo.MyCheese.Name); <span style="color: #008000">//query
for bucket...</span> var bucket = container.Query&lt;Foo, Cheese&gt;( (f, c) =&gt;
f.Entity.Name == <span style="color: #006080">"FooMaster"</span> || c.Entity.Name
== <span style="color: #006080">"MyCheese"</span> ); var f1 = bucket.GetEntities&lt;Foo&gt;().Single();
var c1 = bucket.GetEntities&lt;Cheese&gt;().Single();</pre>
        </div>
        <p>
The calls to <strong>GetEntities&lt;T&gt;</strong> returns <strong>IEnumerable&lt;SsdsEntity&lt;T&gt;&gt;</strong> again. 
However, this was done in a single call to SSDS instead of multiple calls per T.
</p>
        <h3>Paging
</h3>
        <p>
As I mentioned earlier, I wanted the developer to understand what they were doing
when they called each method, so I decided to make paging explicit.  If I had
potentially millions of entities in SSDS, it would be a bad mistake to allow a developer
to issue a simple query that seamlessly paged the items back - especially if the query
was something like <em>e =&gt; e.Id != ""</em>.  Here is how I handled paging:
</p>
        <div>
          <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">var container = ctx.OpenContainer(<span style="color: #006080">"paging"</span>);
List&lt;Foo&gt; items = <span style="color: #0000ff">new</span> List&lt;Foo&gt;(); <span style="color: #0000ff">int</span> i
= 1; container.PagedQuery&lt;Foo&gt;( e =&gt; e.Entity.Size != 0, c =&gt; { Console.WriteLine(<span style="color: #006080">"Got
Page {0}"</span>, i++); items.AddRange(c.Select(s =&gt; s.Entity)); } ); Console.WriteLine(items.Count);</pre>
        </div>
        <p>
The <strong>PagedQuery&lt;T&gt;</strong> method takes two arguments.  One is
the standard <strong>Expression&lt;Func&lt;SsdsEntity&lt;T&gt;, bool&gt;&gt;</strong> that
you use to specify the WHERE clause for SSDS, and the other is <strong>Action&lt;IEnumerable&lt;SsdsEntity&lt;T&gt;&gt;&gt;</strong> which
represents a delegate that takes an <strong>IEnumerable&lt;SsdsEntity&lt;T&gt;&gt;</strong> and
has a void return.  This is a delegate you provide that does something with the
500 entities returned per page (it gets called once per page).  Here, I am just
adding them into a <strong>List&lt;T&gt;</strong>, but I could easily be doing anything
else here.  Under the covers, this is adding the paging term dynamically into
the expression tree that is evaluated.
</p>
        <h3>What's next
</h3>
        <p>
This is a good head start on using the REST API with SSDS today.  However, there
are a number of optimizations that could be made to the model: additional overloads,
perhaps some extension methods for common operations, etc. 
</p>
        <p>
As new features are added, I will endeavor to update this as well (blob support comes
to mind here).  Additionally, I have a few optimizations planned around concurrency
for CRUD operations.  
</p>
        <p>
I have published this out to Code Gallery and I welcome feedback and bug fixes.  <a href="http://code.msdn.microsoft.com/ssdsrest">Linked
here</a>.
</p>
        <img width="0" height="0" src="http://dunnry.com/blog/aggbug.ashx?id=b37072b9-1fe8-4785-9df3-00861ab346f7" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Working with Objects in SSDS Part 2</title>
    <link rel="alternate" type="text/html" href="http://dunnry.com/blog/WorkingWithObjectsInSSDSPart2.aspx" />
    <id>http://dunnry.com/blog/PermaLink,guid,bdbc0cbd-e845-49e9-9e43-52a079bda687.aspx</id>
    <published>2008-06-26T16:03:54.7936682-04:00</published>
    <updated>2008-06-26T16:05:37.9037031-04:00</updated>
    <category term=".NET" label=".NET" scheme="http://dunnry.com/blog/CategoryView,category,.NET.aspx" />
    <category term="Cloud Services" label="Cloud Services" scheme="http://dunnry.com/blog/CategoryView,category,Cloud%2BServices.aspx" />
    <category term="SSDS" label="SSDS" scheme="http://dunnry.com/blog/CategoryView,category,SSDS.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
This is the second post in my series on working with SQL Server Data Service (SSDS)
and objects.  For background, you should read my post on <a href="http://dunnry.com/blog/SerializationInSSDS.aspx">Serializing
Objects in SSDS</a> and the <a href="http://dunnry.com/blog/WorkingWithObjectsInSSDSPart1.aspx">first
post</a> in this series.
</p>
        <p>
Last time I showed how to create a general purpose serializer for SSDS using the standard <strong>XmlSerializer</strong> class
in .NET.  I created a shell entity or a 'thin veneer' for objects called <strong>SsdsEntity&lt;T&gt;</strong>,
where T was any POCO (plain old C#/CLR object).  This allowed me to abstract
away the metadata properties required for SSDS without changing my actual POCO object
(which, I noted was lame to do).
</p>
        <p>
If we decide that we will use SSDS to interact with POCO T, an interesting situation
arises.  Namely, once we have defined T, we have in fact defined a schema - albeit
one only enforced in code you write and not by the SSDS service itself.  One
of the advantages of using something like SSDS is that you have a lot of flexibility
in storing entities  (hence the term 'flexible entity') without conforming to
schema.  Since, I want to support this flexibility, it means I need to think
of a way to support not only the schema implied by T, but also additional and arbitrary
properties that a user might consider.
</p>
        <p>
Some may wonder why we need this flexibility:  after all, why not just change
T to support whatever we like?  The issue comes up most often with code you do
not control.  If you already have an existing codebase with objects that you
would like to store in SSDS, it might not be practical or even possible to change
the T to add additional schema.
</p>
        <p>
Even if you completely control the codebase, expressing relationships between CLR
objects and expressing relationships between things in your data are two different
ideas - sometimes this problem has been termed 'impedance mismatch'.
</p>
        <p>
In the CLR, if two objects are related, they are often part of a collection, or they
refer to an instance on another object.  This is easy to express in the CLR (e.g. <strong>Instance.ChildrenCollection["key"]</strong>). 
In your typical datasource, this same relationship is done using foreign keys to refer
to other entities.
</p>
        <p>
Consider the following classes:
</p>
        <div>
          <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
            <span style="color: #0000ff">public</span>
            <span style="color: #0000ff">class</span> Employee
{ <span style="color: #0000ff">public</span><span style="color: #0000ff">string</span> EmployeeId
{ get; set; } <span style="color: #0000ff">public</span><span style="color: #0000ff">string</span> Name
{ get; set; } <span style="color: #0000ff">public</span> DateTime HireDate { get;
set; } <span style="color: #0000ff">public</span> Employee Manager { get; set; } <span style="color: #0000ff">public</span> Project[]
Projects { get; set; } } <span style="color: #0000ff">public</span><span style="color: #0000ff">class</span> Project
{ <span style="color: #0000ff">public</span><span style="color: #0000ff">string</span> ProjectId
{ get; set; } <span style="color: #0000ff">public</span><span style="color: #0000ff">string</span> Name
{ get; set; } <span style="color: #0000ff">public</span><span style="color: #0000ff">string</span> BillCode
{ get; set; } }</pre>
        </div>
        <p>
Here we see that the <strong>Employee</strong> class refers to itself as well as contains
a collection of related projects (<strong>Project</strong> class) that the employee
works on.  SSDS only supports simple scalar types and no arrays or nested objects
today, so we cannot directly express this in SSDS.  However, we can decompose
this class and store the bits separately and then reassemble later.  First, let's
see what that looks like and then we can see how it was done:
</p>
        <div>
          <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">var projects = <span style="color: #0000ff">new</span> Project[]
{ <span style="color: #0000ff">new</span> Project { BillCode = <span style="color: #006080">"123"</span>,
Name = <span style="color: #006080">"TPS Slave"</span>, ProjectId = <span style="color: #006080">"PID01"</span>}, <span style="color: #0000ff">new</span> Project
{ BillCode = <span style="color: #006080">"124"</span>, Name = <span style="color: #006080">"Programmer"</span>,
ProjectId = <span style="color: #006080">"PID02"</span> } }; var bill = <span style="color: #0000ff">new</span> Employee
{ EmployeeId = <span style="color: #006080">"EMP01"</span>, HireDate = DateTime.Now.AddMonths(-1),
Manager = <span style="color: #0000ff">null</span>, Name = <span style="color: #006080">"Bill
Lumbergh"</span>, Projects = <span style="color: #0000ff">new</span> Project[] {}
}; var peter = <span style="color: #0000ff">new</span> Employee { EmployeeId = <span style="color: #006080">"EMP02"</span>,
HireDate = DateTime.Now, Manager = bill, Name = <span style="color: #006080">"Peter
Gibbons"</span>, Projects = projects }; var cloudpeter = <span style="color: #0000ff">new</span> SsdsEntity&lt;Employee&gt;
{ Entity = peter, Id = peter.EmployeeId }; var cloudbill = <span style="color: #0000ff">new</span> SsdsEntity&lt;Employee&gt;
{ Entity = bill, Id = bill.EmployeeId }; <span style="color: #008000">//here is how
we add flexible props</span> cloudpeter.Add&lt;<span style="color: #0000ff">string</span>&gt;(<span style="color: #006080">"ManagerId"</span>,
peter.Manager.EmployeeId); var table = _context.OpenContainer(<span style="color: #006080">"initech"</span>);
table.Insert(cloudpeter); table.Insert(cloudbill); var cloudprojects = peter.Projects
.Select(s =&gt; <span style="color: #0000ff">new</span> SsdsEntity&lt;Project&gt;
{ Entity = s, Id = Guid.NewGuid().ToString() }); <span style="color: #008000">//add
some metadata to track the project to employee</span><span style="color: #0000ff">foreach</span> (var
proj <span style="color: #0000ff">in</span> cloudprojects) { proj.Add&lt;<span style="color: #0000ff">string</span>&gt;(<span style="color: #006080">"RelatedEmployee"</span>,
peter.EmployeeId); table.Insert(proj); }</pre>
        </div>
        <p>
All this code does is create two employees and two projects and set the relationships
between them.  Using the <strong>Add&lt;K&gt;</strong> method, I can insert any
primitive type to go along for the ride with the POCO.  If we query the container
now, this is what we see:
</p>
        <div>
          <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">s:EntitySet</span>
            <span style="color: #ff0000">xmlns:s</span>
            <span style="color: #0000ff">="http://schemas.microsoft.com/sitka/2008/03/"</span>
            <span style="color: #ff0000">xmlns:xsi</span>
            <span style="color: #0000ff">="http://www.w3.org/2001/XMLSchema-instance"</span>
            <span style="color: #ff0000">xmlns:x</span>
            <span style="color: #0000ff">="http://www.w3.org/2001/XMLSchema"</span>
            <span style="color: #0000ff">&gt;</span>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">Project</span>
            <span style="color: #0000ff">&gt;</span>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">s:Id</span>
            <span style="color: #0000ff">&gt;</span>2ffd7a92-2a3b-4cd8-a5f7-55f40c3ba2b0<span style="color: #0000ff">&lt;/</span><span style="color: #800000">s:Id</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">s:Version</span><span style="color: #0000ff">&gt;</span>1<span style="color: #0000ff">&lt;/</span><span style="color: #800000">s:Version</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">ProjectId</span><span style="color: #ff0000">xsi:type</span><span style="color: #0000ff">="x:string"</span><span style="color: #0000ff">&gt;</span>PID01<span style="color: #0000ff">&lt;/</span><span style="color: #800000">ProjectId</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Name</span><span style="color: #ff0000">xsi:type</span><span style="color: #0000ff">="x:string"</span><span style="color: #0000ff">&gt;</span>TPS
Slave<span style="color: #0000ff">&lt;/</span><span style="color: #800000">Name</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">BillCode</span><span style="color: #ff0000">xsi:type</span><span style="color: #0000ff">="x:string"</span><span style="color: #0000ff">&gt;</span>123<span style="color: #0000ff">&lt;/</span><span style="color: #800000">BillCode</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">RelatedEmployee</span><span style="color: #ff0000">xsi:type</span><span style="color: #0000ff">="x:string"</span><span style="color: #0000ff">&gt;</span>EMP02<span style="color: #0000ff">&lt;/</span><span style="color: #800000">RelatedEmployee</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Project</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Project</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">s:Id</span><span style="color: #0000ff">&gt;</span>892dbb1e-ba47-4c87-80e6-64fbb46da935<span style="color: #0000ff">&lt;/</span><span style="color: #800000">s:Id</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">s:Version</span><span style="color: #0000ff">&gt;</span>1<span style="color: #0000ff">&lt;/</span><span style="color: #800000">s:Version</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">ProjectId</span><span style="color: #ff0000">xsi:type</span><span style="color: #0000ff">="x:string"</span><span style="color: #0000ff">&gt;</span>PID02<span style="color: #0000ff">&lt;/</span><span style="color: #800000">ProjectId</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Name</span><span style="color: #ff0000">xsi:type</span><span style="color: #0000ff">="x:string"</span><span style="color: #0000ff">&gt;</span>Programmer<span style="color: #0000ff">&lt;/</span><span style="color: #800000">Name</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">BillCode</span><span style="color: #ff0000">xsi:type</span><span style="color: #0000ff">="x:string"</span><span style="color: #0000ff">&gt;</span>124<span style="color: #0000ff">&lt;/</span><span style="color: #800000">BillCode</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">RelatedEmployee</span><span style="color: #ff0000">xsi:type</span><span style="color: #0000ff">="x:string"</span><span style="color: #0000ff">&gt;</span>EMP02<span style="color: #0000ff">&lt;/</span><span style="color: #800000">RelatedEmployee</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Project</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Employee</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">s:Id</span><span style="color: #0000ff">&gt;</span>EMP01<span style="color: #0000ff">&lt;/</span><span style="color: #800000">s:Id</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">s:Version</span><span style="color: #0000ff">&gt;</span>1<span style="color: #0000ff">&lt;/</span><span style="color: #800000">s:Version</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">EmployeeId</span><span style="color: #ff0000">xsi:type</span><span style="color: #0000ff">="x:string"</span><span style="color: #0000ff">&gt;</span>EMP01<span style="color: #0000ff">&lt;/</span><span style="color: #800000">EmployeeId</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Name</span><span style="color: #ff0000">xsi:type</span><span style="color: #0000ff">="x:string"</span><span style="color: #0000ff">&gt;</span>Bill
Lumbergh<span style="color: #0000ff">&lt;/</span><span style="color: #800000">Name</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">HireDate</span><span style="color: #ff0000">xsi:type</span><span style="color: #0000ff">="x:dateTime"</span><span style="color: #0000ff">&gt;</span>2008-05-25T23:59:49<span style="color: #0000ff">&lt;/</span><span style="color: #800000">HireDate</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Employee</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Employee</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">s:Id</span><span style="color: #0000ff">&gt;</span>EMP02<span style="color: #0000ff">&lt;/</span><span style="color: #800000">s:Id</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">s:Version</span><span style="color: #0000ff">&gt;</span>1<span style="color: #0000ff">&lt;/</span><span style="color: #800000">s:Version</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">EmployeeId</span><span style="color: #ff0000">xsi:type</span><span style="color: #0000ff">="x:string"</span><span style="color: #0000ff">&gt;</span>EMP02<span style="color: #0000ff">&lt;/</span><span style="color: #800000">EmployeeId</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Name</span><span style="color: #ff0000">xsi:type</span><span style="color: #0000ff">="x:string"</span><span style="color: #0000ff">&gt;</span>Peter
Gibbons<span style="color: #0000ff">&lt;/</span><span style="color: #800000">Name</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">HireDate</span><span style="color: #ff0000">xsi:type</span><span style="color: #0000ff">="x:dateTime"</span><span style="color: #0000ff">&gt;</span>2008-06-25T23:59:49<span style="color: #0000ff">&lt;/</span><span style="color: #800000">HireDate</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">ManagerId</span><span style="color: #ff0000">xsi:type</span><span style="color: #0000ff">="x:string"</span><span style="color: #0000ff">&gt;</span>EMP01<span style="color: #0000ff">&lt;/</span><span style="color: #800000">ManagerId</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Employee</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">s:EntitySet</span><span style="color: #0000ff">&gt;</span></pre>
        </div>
        <p>
As you can see, I have stored extra data in my 'flexible' entity with the <strong>ManagerId</strong> property
(on one entity) and <strong>RelatedEmployee</strong> property on the <strong>Project</strong> kinds. 
This allows me to figure out later what objects are related to each other since we
can't model the CLR objects relationships directly.  Let's see how this was done.
</p>
        <div>
          <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
            <span style="color: #0000ff">public</span>
            <span style="color: #0000ff">class</span> SsdsEntity&lt;T&gt; <span style="color: #0000ff">where</span> T: <span style="color: #0000ff">class</span> {
Dictionary&lt;<span style="color: #0000ff">string</span>, <span style="color: #0000ff">object</span>&gt;
_propertyBucket = <span style="color: #0000ff">new</span> Dictionary&lt;<span style="color: #0000ff">string</span>, <span style="color: #0000ff">object</span>&gt;(); <span style="color: #0000ff">public</span> SsdsEntity()
{ } [XmlIgnore] <span style="color: #0000ff">public</span> Dictionary&lt;<span style="color: #0000ff">string</span>, <span style="color: #0000ff">object</span>&gt;
PropertyBucket { get { <span style="color: #0000ff">return</span> _propertyBucket;
} } [XmlAnyElement] <span style="color: #0000ff">public</span> XElement[] Attributes
{ get { <span style="color: #008000">//using XElement is much easier than XmlElement
to build</span><span style="color: #008000">//take all properties on object instance
and build XElement</span> var props = from prop <span style="color: #0000ff">in</span><span style="color: #0000ff">typeof</span>(T).GetProperties()
let val = prop.GetValue(<span style="color: #0000ff">this</span>.Entity, <span style="color: #0000ff">null</span>) <span style="color: #0000ff">where</span> prop.GetSetMethod()
!= <span style="color: #0000ff">null</span> &amp;&amp; allowableTypes.Contains(prop.PropertyType)
&amp;&amp; val != <span style="color: #0000ff">null</span> select <span style="color: #0000ff">new</span> XElement(prop.Name, <span style="color: #0000ff">new</span> XAttribute(Constants.xsi
+ <span style="color: #006080">"type"</span>, XsdTypeResolver.Solve(prop.PropertyType)),
EncodeValue(val) ); <span style="color: #008000">//Then stuff in any extra stuff you
want</span> var extra = _propertyBucket.Select( e =&gt; <span style="color: #0000ff">new</span> XElement(e.Key, <span style="color: #0000ff">new</span> XAttribute(Constants.xsi
+ <span style="color: #006080">"type"</span>, XsdTypeResolver.Solve(e.Value.GetType())),
EncodeValue(e.Value) ) ); <span style="color: #0000ff">return</span> props.Union(extra).ToArray();
} set { <span style="color: #008000">//wrap the XElement[] with the name of the type</span> var
xml = <span style="color: #0000ff">new</span> XElement(<span style="color: #0000ff">typeof</span>(T).Name, <span style="color: #0000ff">value</span>);
var xs = <span style="color: #0000ff">new</span> XmlSerializer(<span style="color: #0000ff">typeof</span>(T)); <span style="color: #008000">//xml.CreateReader()
cannot be used as it won't support base64 content</span> XmlTextReader reader = <span style="color: #0000ff">new</span> XmlTextReader(
xml.ToString(), XmlNodeType.Document, <span style="color: #0000ff">null</span> ); <span style="color: #0000ff">this</span>.Entity
= (T)xs.Deserialize(reader); <span style="color: #008000">//now deserialize the other
stuff left over into the property bucket...</span> var stuff = from v <span style="color: #0000ff">in</span><span style="color: #0000ff">value</span>.AsEnumerable()
let props = <span style="color: #0000ff">typeof</span>(T).GetProperties().Select(s
=&gt; s.Name) <span style="color: #0000ff">where</span> !props.Contains(v.Name.ToString())
select v; <span style="color: #0000ff">foreach</span> (var item <span style="color: #0000ff">in</span> stuff)
{ _propertyBucket.Add( item.Name.ToString(), DecodeValue( item.Attribute(Constants.xsi
+ <span style="color: #006080">"type"</span>).Value, item.Value) ); } } } <span style="color: #0000ff">public</span><span style="color: #0000ff">void</span> Add&lt;K&gt;(<span style="color: #0000ff">string</span> key,
K <span style="color: #0000ff">value</span>) { <span style="color: #0000ff">if</span> (!allowableTypes.Contains(<span style="color: #0000ff">typeof</span>(K))) <span style="color: #0000ff">throw</span><span style="color: #0000ff">new</span> ArgumentException(
String.Format( <span style="color: #006080">"Type {0} not supported in SsdsEntity"</span>, <span style="color: #0000ff">typeof</span>(K).Name)
); <span style="color: #0000ff">if</span> (!_propertyBucket.ContainsKey(key)) { _propertyBucket.Add(key, <span style="color: #0000ff">value</span>);
} <span style="color: #0000ff">else</span> { <span style="color: #008000">//replace
the value</span> _propertyBucket.Remove(key); _propertyBucket.Add(key, <span style="color: #0000ff">value</span>);
} } }</pre>
        </div>
        <p>
I have omitted the parts of <strong>SsdsEntity&lt;T&gt;</strong> from the first post
that didn't change.  The only other addition you don't see here is a helper method
called <strong>DecodeValue</strong>, which as you might guess, interprets the string
value in XML and attempts to cast it to a CLR type based on the xsi:type that comes
back.
</p>
        <p>
All we did here was add a <strong>Dictionary&lt;string, object&gt;</strong> property
called <strong>PropertyBucket</strong> that holds our extra stuff we want to associate
with our T instance.  Then in the getter and setter for the <strong>XElement[]</strong> property
called <strong>Attributes</strong>, we are adding them into our array of <strong>XElement</strong> as
well as pulling them back out on deserialization and stuffing them back into the Dictionary. 
With this simple addition, we have fixed our in flexibility (or lack thereof) problem. 
We are still limited to the simple scalar types, but as you can see you can work around
this in a lot of cases by decomposing the objects down enough to be able to recreate
them later.
</p>
        <p>
The <strong>Add&lt;K&gt;</strong> method is a convenience only as we could operate
directly against the Dictionary.  I also could have chosen to keep the Dictionary
property bucket private and not expose it.  That would have worked just fine
for serialization, but I wanted to also be able to query it later.
</p>
        <p>
In my last post, I said I would introduce a library where all this code is coming
from, but I didn't realize at the time how long this post would be and that I still
need to cover querying.  So... next time, I will finish up this series by explaining
how the strongly typed query model works and how all these pieces fit together to
recompose the data back into objects (and release the library).
</p>
        <img width="0" height="0" src="http://dunnry.com/blog/aggbug.ashx?id=bdbc0cbd-e845-49e9-9e43-52a079bda687" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Working with Objects in SSDS Part 1</title>
    <link rel="alternate" type="text/html" href="http://dunnry.com/blog/WorkingWithObjectsInSSDSPart1.aspx" />
    <id>http://dunnry.com/blog/PermaLink,guid,2021b648-8af2-4702-95f5-c5ec1455c1e1.aspx</id>
    <published>2008-06-17T23:17:10.2667703-04:00</published>
    <updated>2008-06-17T23:17:10.2667703-04:00</updated>
    <category term=".NET" label=".NET" scheme="http://dunnry.com/blog/CategoryView,category,.NET.aspx" />
    <category term="Cloud Services" label="Cloud Services" scheme="http://dunnry.com/blog/CategoryView,category,Cloud%2BServices.aspx" />
    <category term="Design" label="Design" scheme="http://dunnry.com/blog/CategoryView,category,Design.aspx" />
    <category term="SSDS" label="SSDS" scheme="http://dunnry.com/blog/CategoryView,category,SSDS.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://dunnry.com/blog/SerializationInSSDS.aspx">Last time</a> we talked
about SQL Server Data Services and serializing objects, we discussed how easy it was
to use the <strong>XmlSerializer</strong> to deserialize objects using the REST interface. 
The problem was that when we serialized objects using the <strong>XmlSerializer</strong>,
it left out the xsi type declarations that we needed.  I gave two possible solutions
to this problem - one that used the <strong>XmlSerializer</strong> and 'fixed' the
output after the fact, and the other built the XML that we needed using XLINQ and
Reflection.
</p>
        <p>
Today, I am going to talk about a third technique that I have been using lately that
I like better.  It uses some of the previous techniques and leverages a few tricks
with <strong>XmlSerializer</strong> to get what I want.  First, let's start with
a POCO (plain ol' C# object) class that we would like to use with SSDS.
</p>
        <div>
          <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
            <span style="color: #0000ff">public</span>
            <span style="color: #0000ff">class</span> Foo
{ <span style="color: #0000ff">public</span><span style="color: #0000ff">string</span> Name
{ get; set; } <span style="color: #0000ff">public</span><span style="color: #0000ff">int</span> Size
{ get; set; } <span style="color: #0000ff">public</span><span style="color: #0000ff">bool</span> IsPublic
{ get; set; } }</pre>
        </div>
        <p>
In it's correctly serialized form, it looks like this on the wire:
</p>
        <div>
          <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">Foo</span>
            <span style="color: #ff0000">xmlns:s</span>
            <span style="color: #0000ff">="http://schemas.microsoft.com/sitka/2008/03/"</span>
            <span style="color: #ff0000">xmlns:xsi</span>
            <span style="color: #0000ff">="http://www.w3.org/2001/XMLSchema-instance"</span>
            <span style="color: #ff0000">xmlns:x</span>
            <span style="color: #0000ff">="http://www.w3.org/2001/XMLSchema"</span>
            <span style="color: #0000ff">&gt;</span>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">s:Id</span>
            <span style="color: #0000ff">&gt;</span>someid<span style="color: #0000ff">&lt;/</span><span style="color: #800000">s:Id</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">s:Version</span><span style="color: #0000ff">&gt;</span>1<span style="color: #0000ff">&lt;/</span><span style="color: #800000">s:Version</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Name</span><span style="color: #ff0000">xsi:type</span><span style="color: #0000ff">="x:string"</span><span style="color: #0000ff">&gt;</span>My
Foo<span style="color: #0000ff">&lt;/</span><span style="color: #800000">Name</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Size</span><span style="color: #ff0000">xsi:type</span><span style="color: #0000ff">="x:decimal"</span><span style="color: #0000ff">&gt;</span>10<span style="color: #0000ff">&lt;/</span><span style="color: #800000">Size</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">IsPublic</span><span style="color: #ff0000">xsi:type</span><span style="color: #0000ff">="x:boolean"</span><span style="color: #0000ff">&gt;</span>false<span style="color: #0000ff">&lt;/</span><span style="color: #800000">IsPublic</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Foo</span><span style="color: #0000ff">&gt;</span></pre>
        </div>
        <p>
You'll notice that we have the additional system metadata attributes "Id" and "Version"
in the markup.  We can account for the metadata attributes by doing something
cheesy like deriving from a base class:
</p>
        <div>
          <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
            <span style="color: #0000ff">public</span>
            <span style="color: #0000ff">abstract</span>
            <span style="color: #0000ff">class</span> Cheese
{ <span style="color: #0000ff">public</span><span style="color: #0000ff">string</span> Id
{ get; set; } <span style="color: #0000ff">public</span><span style="color: #0000ff">int</span> Version
{ get; set; } }</pre>
        </div>
        <p>
However this is very unnatural as our classes would all have to derive from our "Cheese"
abstract base class (ABC).
</p>
        <div>
          <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
            <span style="color: #0000ff">public</span>
            <span style="color: #0000ff">class</span> Foo
: Cheese { <span style="color: #0000ff">public</span><span style="color: #0000ff">string</span> Name
{ get; set; } <span style="color: #0000ff">public</span><span style="color: #0000ff">int</span> Size
{ get; set; } <span style="color: #0000ff">public</span><span style="color: #0000ff">bool</span> IsPublic
{ get; set; } }</pre>
        </div>
        <p>
Developers familiar with remoting in .NET should be cringing right now as they remember
the hassles associated with deriving from <strong>MarshalByRefObject</strong>. 
In a world without multiple inheritance, this can be painful.  I want a model
where I can use arbitrary POCO objects (<a href="http://haacked.com/archive/2008/06/13/ras-syndrome.aspx">redundant</a>,
yes I know) and not be forced to derive from anything or do what I would otherwise
term unnatural acts.
</p>
        <p>
What if instead, we derived a generic entity that could contain any other entity?
</p>
        <div>
          <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
            <span style="color: #0000ff">public</span>
            <span style="color: #0000ff">class</span> SsdsEntity&lt;T&gt; <span style="color: #0000ff">where</span> T: <span style="color: #0000ff">class</span> { <span style="color: #0000ff">string</span> _kind; <span style="color: #0000ff">public</span> SsdsEntity()
{ } [XmlElement(Namespace = <span style="color: #006080">@"http://schemas.microsoft.com/sitka/2008/03/"</span>)] <span style="color: #0000ff">public</span><span style="color: #0000ff">string</span> Id
{ get; set; } [XmlIgnore] <span style="color: #0000ff">public</span><span style="color: #0000ff">string</span> Kind
{ get { <span style="color: #0000ff">if</span> (String.IsNullOrEmpty(_kind)) { _kind
= <span style="color: #0000ff">typeof</span>(T).Name; } <span style="color: #0000ff">return</span> _kind;
} set { _kind = <span style="color: #0000ff">value</span>; } } [XmlElement(Namespace
= <span style="color: #006080">@"http://schemas.microsoft.com/sitka/2008/03/"</span>)] <span style="color: #0000ff">public</span><span style="color: #0000ff">int</span> Version
{ get; set; } [XmlIgnore] <span style="color: #0000ff">public</span> T Entity { get;
set; } }</pre>
        </div>
        <p>
In this case, we have simply wrapped the POCO that we care about in a class that knows
about the specifics of the SSDS wire format (or more accurately could serialize down
to the wire format).
</p>
        <p>
This <strong>SsdsEntity&lt;T&gt;</strong> is easy to use and provides access to the
strongly typed object via the Entity property.
</p>
        <p>
          <a href="http://dunnry.com/blog/content/binary/WindowsLiveWriter/SerializationinSSDSRevisited_BEC9/foomembers_2.png">
            <img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="293" alt="foomembers" src="http://dunnry.com/blog/content/binary/WindowsLiveWriter/SerializationinSSDSRevisited_BEC9/foomembers_thumb.png" width="487" border="0" />
          </a>
        </p>
        <p>
Now, we just have to figure out how to serialize the <strong>SsdsEntity&lt;Foo&gt;</strong> object
and we know that the metadata attributes are taken care of and our original POCO object
that we care about is included.  I call it wrapping POCOs in a thin SSDS veneer.
</p>
        <p>
The trick to this is to add a bucket of XElement objects on the <strong>SsdsEntity&lt;T&gt;</strong> class
that will hold our public properties on our class T (i.e. 'Foo' class).  It looks
something like this:
</p>
        <div>
          <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">[XmlAnyElement]
<span style="color: #0000ff">public</span> XElement[]
Attributes { get { <span style="color: #008000">//using XElement is much easier than
XmlElement to build</span><span style="color: #008000">//take all properties on object
instance and build XElement</span> var props = from prop <span style="color: #0000ff">in</span><span style="color: #0000ff">typeof</span>(T).GetProperties()
let val = prop.GetValue(<span style="color: #0000ff">this</span>.Entity, <span style="color: #0000ff">null</span>) <span style="color: #0000ff">where</span> prop.GetSetMethod()
!= <span style="color: #0000ff">null</span> &amp;&amp; allowableTypes.Contains(prop.PropertyType)
&amp;&amp; val != <span style="color: #0000ff">null</span> select <span style="color: #0000ff">new</span> XElement(prop.Name, <span style="color: #0000ff">new</span> XAttribute(Constants.xsi
+ <span style="color: #006080">"type"</span>, XsdTypeResolver.Solve(prop.PropertyType)),
EncodeValue(val) ); <span style="color: #0000ff">return</span> props.ToArray(); }
set { <span style="color: #008000">//wrap the XElement[] with the name of the type</span> var
xml = <span style="color: #0000ff">new</span> XElement(<span style="color: #0000ff">typeof</span>(T).Name, <span style="color: #0000ff">value</span>);
var xs = <span style="color: #0000ff">new</span> XmlSerializer(<span style="color: #0000ff">typeof</span>(T)); <span style="color: #008000">//xml.CreateReader()
cannot be used as it won't support base64 content</span> XmlTextReader reader = <span style="color: #0000ff">new</span> XmlTextReader(
xml.ToString(), XmlNodeType.Document, <span style="color: #0000ff">null</span>); <span style="color: #0000ff">this</span>.Entity
= (T)xs.Deserialize(reader); } }</pre>
        </div>
        <p>
In the getter, we use Reflection and pull back a list of all the public properties
on the T object and build an array of <strong>XElement</strong>.  This is the
same technique I used in my first post on serialization.  The 'allowableTypes'
object is a <strong>HashSet&lt;Type&gt;</strong> that we use to figure out which property
types we can support in the service (DateTime, numeric, string, boolean, and byte[]). 
When this property serializes, the <strong>XElement</strong>s are simply added to
the markup.
</p>
        <p>
The <strong>EncodeValue</strong> method shown is a simple helper method that correctly
encodes string values, boolean, dates, integers, and byte[] values for the attribute. 
Finally, we are using a helper method that returns from a <strong>Dictionary&lt;Type,string&gt;</strong> the
correct xsi type for the required attribute (as determined from the property type).
</p>
        <p>
For deserialization, what happens is that the <strong>[XmlAnyElement]</strong> attribute
causes all unmapped attributes (in this case, all non-system metadata attributes)
to be collected in a collection of <strong>XElement</strong>.  When we deserialize,
if we simply wrap an enclosing element around this <strong>XElement</strong> collection,
it is exactly what we need for deserialization of T.  This is shown in the setter
implementation.
</p>
        <p>
It might look a little complicated, but now simple serialization will just work via
the <strong>XmlSerializer</strong>.  Here is one such implementation:
</p>
        <div>
          <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
            <span style="color: #0000ff">public</span>
            <span style="color: #0000ff">string</span> Serialize(SsdsEntity&lt;T&gt;
entity) { <span style="color: #008000">//add a bunch of namespaces and override the
default ones too</span> XmlSerializerNamespaces namespaces = <span style="color: #0000ff">new</span> XmlSerializerNamespaces();
namespaces.Add(<span style="color: #006080">"s"</span>, Constants.ns.NamespaceName);
namespaces.Add(<span style="color: #006080">"x"</span>, Constants.x.NamespaceName);
namespaces.Add(<span style="color: #006080">"xsi"</span>, Constants.xsi.NamespaceName);
var xs = <span style="color: #0000ff">new</span> XmlSerializer( entity.GetType(), <span style="color: #0000ff">new</span> XmlRootAttribute(<span style="color: #0000ff">typeof</span>(T).Name)
); XmlWriterSettings xws = <span style="color: #0000ff">new</span> XmlWriterSettings();
xws.Indent = <span style="color: #0000ff">true</span>; xws.OmitXmlDeclaration = <span style="color: #0000ff">true</span>; <span style="color: #0000ff">using</span> (var
ms = <span style="color: #0000ff">new</span> MemoryStream()) { <span style="color: #0000ff">using</span> (XmlWriter
writer = XmlWriter.Create(ms, xws)) { xs.Serialize(writer, entity, namespaces); ms.Position
= 0; <span style="color: #008000">//reset to beginning</span><span style="color: #0000ff">using</span> (var
sr = <span style="color: #0000ff">new</span> StreamReader(ms)) { <span style="color: #0000ff">return</span> sr.ReadToEnd();
} } } }</pre>
        </div>
        <p>
Deserialization is even easier since we are starting with the XML representation and
don't have to build a Stream in memory.
</p>
        <div>
          <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
            <span style="color: #0000ff">public</span> SsdsEntity&lt;T&gt;
Deserialize(XElement node) { var xs = <span style="color: #0000ff">new</span> XmlSerializer( <span style="color: #0000ff">typeof</span>(SsdsEntity&lt;T&gt;), <span style="color: #0000ff">new</span> XmlRootAttribute(<span style="color: #0000ff">typeof</span>(T).Name)
); <span style="color: #008000">//xml.CreateReader() cannot be used as it won't support
base64 content</span> XmlTextReader reader = <span style="color: #0000ff">new</span> XmlTextReader(
node.ToString(), XmlNodeType.Document, <span style="color: #0000ff">null</span>); <span style="color: #0000ff">return</span> (SsdsEntity&lt;T&gt;)xs.Deserialize(reader);
}</pre>
        </div>
        <p>
If you notice, I am using an <strong>XmlTextReader</strong> to pass to the <strong>XmlSerializer</strong>. 
Unfortunately, the <strong>XmlReader</strong> from XLINQ does not support handling
of base64 content, so this workaround is necessary.
</p>
        <p>
At this point, we have a working serializer/deserializer that can handle arbitrary
POCOs.  There are some limitations of course:
</p>
        <ul>
          <li>
            <font color="#555555">We are limited to the same datatypes that SSDS supports. 
This also means nested objects and arrays are not directly supported.</font>
          </li>
          <li>
            <font color="#555555">We have lost a little of the 'flexible' in the Flexible Entity
(the E in the <a href="http://dunnry.com/blog/EntitiesContainersAndAuthorities.aspx">ACE
model</a>).  We now have a rigid schema defined by SSDS metadata and T public
properties and enforced on our objects.</font>
          </li>
        </ul>
        <p>
In my next post, I will attempt to address some of those limitations and I will introduce
a library that handles most of this for you.
</p>
        <img width="0" height="0" src="http://dunnry.com/blog/aggbug.ashx?id=2021b648-8af2-4702-95f5-c5ec1455c1e1" />
      </div>
    </content>
  </entry>
  <entry>
    <title>LINQPad - not just for LINQ</title>
    <link rel="alternate" type="text/html" href="http://dunnry.com/blog/LINQPadNotJustForLINQ.aspx" />
    <id>http://dunnry.com/blog/PermaLink,guid,ada84666-9fb7-4142-8764-adff11fd8552.aspx</id>
    <published>2008-06-11T13:47:50.9680498-04:00</published>
    <updated>2008-06-11T13:47:50.9680498-04:00</updated>
    <category term=".NET" label=".NET" scheme="http://dunnry.com/blog/CategoryView,category,.NET.aspx" />
    <category term="LINQ" label="LINQ" scheme="http://dunnry.com/blog/CategoryView,category,LINQ.aspx" />
    <category term="Tips" label="Tips" scheme="http://dunnry.com/blog/CategoryView,category,Tips.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
I officially love <a href="http://www.linqpad.net/">LINQPad</a>.  Joe Albahari
has done a great job of introducing a light weight tool that is great for learning
and prototyping LINQ queries.  From what I gather, Joe and Ben Albahari built
this tool as part of <a href="http://www.amazon.com/exec/obidos/ASIN/0596527578/extemporaneou-20-20">their
book</a> offering.  It was so useful, it has taken on a life of its own.
</p>
        <p>
It may not be entirely obvious, but it turns out don't have to use LINQPad solely
for LINQ queries.  You can actually prototype any type of snippet of code. 
I have been using it now instead of <a href="http://www.sliver.com/dotnet/SnippetCompiler/">SnippetCompiler</a> (another
great quick snippet tool).
</p>
        <p>
As an example, here is how to use System.DirectoryServices snippets inside of LINQPad:
</p>
        <p>
Hit F4 to bring up the Advanced Query Properties Window
</p>
        <p>
          <a href="http://dunnry.com/blog/content/binary/WindowsLiveWriter/LINQPadnotjustforLINQ_9627/image_2.png">
            <img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="364" alt="image" src="http://dunnry.com/blog/content/binary/WindowsLiveWriter/LINQPadnotjustforLINQ_9627/image_thumb.png" width="461" border="0" />
          </a>
        </p>
        <p>
Add the System.DirectoryServices.dll reference in the Additional References window,
and then add "System.DirectoryServices" in the Additional Namespace Imports window.
</p>
        <p>
Now, just type your code normally and hit F5 when you are done:
</p>
        <p>
          <a href="http://dunnry.com/blog/content/binary/WindowsLiveWriter/LINQPadnotjustforLINQ_9627/image_6.png">
            <img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="352" alt="image" src="http://dunnry.com/blog/content/binary/WindowsLiveWriter/LINQPadnotjustforLINQ_9627/image_thumb_2.png" width="457" border="0" />
          </a> 
</p>
        <p>
This is a great little tool to have as you can query databases, build LINQ expressions,
and visually inspect the results that come back pretty easily.  Now, as you can
see you can also execute arbitrary code snippets as well.  Highly recommended.
</p>
        <img width="0" height="0" src="http://dunnry.com/blog/aggbug.ashx?id=ada84666-9fb7-4142-8764-adff11fd8552" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Paged Asynchronous LDAP Searches Revisited</title>
    <link rel="alternate" type="text/html" href="http://dunnry.com/blog/PagedAsynchronousLDAPSearchesRevisited.aspx" />
    <id>http://dunnry.com/blog/PermaLink,guid,982fe6ab-e507-4e65-b168-e8c2d3d72a9f.aspx</id>
    <published>2008-06-05T14:56:28.4837348-04:00</published>
    <updated>2008-06-05T14:56:28.4837348-04:00</updated>
    <category term=".NET" label=".NET" scheme="http://dunnry.com/blog/CategoryView,category,.NET.aspx" />
    <category term="Active Directory" label="Active Directory" scheme="http://dunnry.com/blog/CategoryView,category,Active%2BDirectory.aspx" />
    <category term="LDAP" label="LDAP" scheme="http://dunnry.com/blog/CategoryView,category,LDAP.aspx" />
    <category term="Protocols" label="Protocols" scheme="http://dunnry.com/blog/CategoryView,category,Protocols.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
A member in the <a href="http://directoryprogramming.net/forums/9/ShowForum.aspx">book's
forum</a> mentioned some code I had originally posted <a href="http://dunnry.com/blog/AsynchronousLDAPSearchingWithSystemDirectoryServicesProtocols.aspx">here</a> in
the blog for asynchronous, paged searches in System.DirectoryServices.Protocols (SDS.P). 
He questioned whether or not it was thread safe.  I honestly don't know - it
might not be as I didn't test it extensively.
</p>
        <p>
Regardless, I had actually moved on from that code and started using anonymous delegates
for callbacks instead of events.  I liked this pattern a bit better because it
also got rid of the shared resources.
</p>
        <p>
After reading Stephen Toub's <a href="http://msdn.microsoft.com/en-us/magazine/cc337900.aspx">article</a> on
asynchronous stream processing, I learned about the AsyncOperationManager which was
something I was missing in my implementation.  I have been doing a lot lately
with .NET 3.5, LINQ, and lambda expressions, so I also decided to rewrite the anonymous
delegates to lambda expressions.  That is not as big a change, but it is more
concise.
</p>
        <p>
I actively investigated using <a href="http://tomasp.net/blog/csharp-async.aspx">async
iterators</a>, but ultimately I decided closures seemed to be more intuitive for me. 
I might revisit this at some time and change my mind.  Here is my outcome:
</p>
        <div>
          <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
            <span style="color: #0000ff">public</span>
            <span style="color: #0000ff">class</span> AsyncSearcher
{ LdapConnection _connect; <span style="color: #0000ff">public</span> AsyncSearcher(LdapConnection
connection) { <span style="color: #0000ff">this</span>._connect = connection; <span style="color: #0000ff">this</span>._connect.AutoBind
= <span style="color: #0000ff">true</span>; <span style="color: #008000">//will bind
on first search</span> } <span style="color: #0000ff">public</span><span style="color: #0000ff">void</span> BeginPagedSearch( <span style="color: #0000ff">string</span> baseDN, <span style="color: #0000ff">string</span> filter, <span style="color: #0000ff">string</span>[]
attribs, <span style="color: #0000ff">int</span> pageSize, Action&lt;SearchResponse&gt;
page, Action&lt;Exception&gt; completed ) { <span style="color: #0000ff">if</span> (page
== <span style="color: #0000ff">null</span>) <span style="color: #0000ff">throw</span><span style="color: #0000ff">new</span> ArgumentNullException(<span style="color: #006080">"page"</span>);
AsyncOperation asyncOp = AsyncOperationManager.CreateOperation(<span style="color: #0000ff">null</span>);
Action&lt;Exception&gt; done = e =&gt; { <span style="color: #0000ff">if</span> (completed
!= <span style="color: #0000ff">null</span>) asyncOp.Post(<span style="color: #0000ff">delegate</span> {
completed(e); }, <span style="color: #0000ff">null</span>); }; SearchRequest request
= <span style="color: #0000ff">new</span> SearchRequest( baseDN, filter, System.DirectoryServices.Protocols.SearchScope.Subtree,
attribs ); PageResultRequestControl prc = <span style="color: #0000ff">new</span> PageResultRequestControl(pageSize); <span style="color: #008000">//add
the paging control</span> request.Controls.Add(prc); AsyncCallback rc = <span style="color: #0000ff">null</span>;
rc = readResult =&gt; { <span style="color: #0000ff">try</span> { var response = (SearchResponse)_connect.EndSendRequest(readResult); <span style="color: #008000">//let
current thread handle results</span> asyncOp.Post(<span style="color: #0000ff">delegate</span> {
page(response); }, <span style="color: #0000ff">null</span>); var cookie = response.Controls
.Where(c =&gt; c <span style="color: #0000ff">is</span> PageResultResponseControl)
.Select(s =&gt; ((PageResultResponseControl)s).Cookie) .Single(); <span style="color: #0000ff">if</span> (cookie
!= <span style="color: #0000ff">null</span> &amp;&amp; cookie.Length != 0) { prc.Cookie
= cookie; _connect.BeginSendRequest( request, PartialResultProcessing.NoPartialResultSupport,
rc, <span style="color: #0000ff">null</span> ); } <span style="color: #0000ff">else</span> done(<span style="color: #0000ff">null</span>); <span style="color: #008000">//signal
complete</span> } <span style="color: #0000ff">catch</span> (Exception ex) { done(ex);
} }; <span style="color: #008000">//kick off async</span><span style="color: #0000ff">try</span> {
_connect.BeginSendRequest( request, PartialResultProcessing.NoPartialResultSupport,
rc, <span style="color: #0000ff">null</span> ); } <span style="color: #0000ff">catch</span> (Exception
ex) { done(ex); } } }</pre>
        </div>
        <p>
It can be consumed very easily using something like this:
</p>
        <div>
          <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
            <span style="color: #0000ff">class</span> Program
{ <span style="color: #0000ff">static</span> ManualResetEvent _resetEvent = <span style="color: #0000ff">new</span> ManualResetEvent(<span style="color: #0000ff">false</span>); <span style="color: #0000ff">static</span><span style="color: #0000ff">void</span> Main(<span style="color: #0000ff">string</span>[]
args) { <span style="color: #008000">//set these to your environment</span><span style="color: #0000ff">string</span> servername
= <span style="color: #006080">"server.yourdomain.com"</span>; <span style="color: #0000ff">string</span> baseDN
= <span style="color: #006080">"dc=yourdomain,dc=com"</span>; <span style="color: #0000ff">using</span> (LdapConnection
connection = CreateConnection(servername)) { AsyncSearcher searcher = <span style="color: #0000ff">new</span> AsyncSearcher(connection);
searcher.BeginPagedSearch( baseDN, <span style="color: #006080">"(sn=Dunn)"</span>, <span style="color: #0000ff">null</span>,
100, f =&gt; <span style="color: #008000">//runs per page</span> { <span style="color: #0000ff">foreach</span> (var
item <span style="color: #0000ff">in</span> f.Entries) { var entry = item <span style="color: #0000ff">as</span> SearchResultEntry; <span style="color: #0000ff">if</span> (entry
!= <span style="color: #0000ff">null</span>) { Console.WriteLine(entry.DistinguishedName);
} } }, c =&gt; <span style="color: #008000">//runs on error or when done</span> { <span style="color: #0000ff">if</span> (c
!= <span style="color: #0000ff">null</span>) Console.WriteLine(c.ToString()); Console.WriteLine(<span style="color: #006080">"Done"</span>);
_resetEvent.Set(); } ); _resetEvent.WaitOne(); } Console.WriteLine(); Console.WriteLine(<span style="color: #006080">"Finished....
Press Enter to Continue."</span>); Console.ReadLine(); } <span style="color: #0000ff">static</span> LdapConnection
CreateConnection(<span style="color: #0000ff">string</span> server) { LdapConnection
connect = <span style="color: #0000ff">new</span> LdapConnection( <span style="color: #0000ff">new</span> LdapDirectoryIdentifier(server), <span style="color: #0000ff">null</span>,
AuthType.Negotiate ); connect.SessionOptions.ProtocolVersion = 3; connect.SessionOptions.ReferralChasing
= ReferralChasingOptions.None; connect.SessionOptions.Sealing = <span style="color: #0000ff">true</span>;
connect.SessionOptions.Signing = <span style="color: #0000ff">true</span>; <span style="color: #0000ff">return</span> connect;
} } </pre>
        </div>
        <p>
 
</p>
        <p>
The important thing to note is that because everything is running asynchronously,
it is totally possible for the end delegate to be invoked before the paging delegate
has a chance to finish processing results (depending on how complicated your code
is).  You would need to compensate for this yourself.
</p>
        <p>
This client is a console application, so I am using a ManualResetEvent just to prevent
it from closing before finishing.  You wouldn't need to do this in a WinForms
or WPF app.
</p>
        <p>
I am sure there are other optimizations you could make to pass in parameters or even
other directory controls.  However, the general pattern should apply.
</p>
        <img width="0" height="0" src="http://dunnry.com/blog/aggbug.ashx?id=982fe6ab-e507-4e65-b168-e8c2d3d72a9f" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Continental Offers Million Miler Program</title>
    <link rel="alternate" type="text/html" href="http://dunnry.com/blog/ContinentalOffersMillionMilerProgram.aspx" />
    <id>http://dunnry.com/blog/PermaLink,guid,c83f5f74-9b35-4086-bafc-4c8388b572c7.aspx</id>
    <published>2008-06-02T20:12:34.6850698-04:00</published>
    <updated>2008-06-02T20:12:34.6850698-04:00</updated>
    <category term="Personal" label="Personal" scheme="http://dunnry.com/blog/CategoryView,category,Personal.aspx" />
    <category term="Tips" label="Tips" scheme="http://dunnry.com/blog/CategoryView,category,Tips.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
As a frequent flier and former Continental Platinum Elite member, I was always jealous
of the American Airlines program where you got lifetime status on the airline whenever
you achieved a million air miles with them.  However, I was browsing the FlyerTalk
forum when I noticed this announcement.  I can't wait to see how far away I am
on it (probably 600K or more away is my guess).
</p>
        <p>
          <a href="http://www.flyertalk.com/forum/showthread.php?t=830159">FlyerTalk Announcment</a>
        </p>
        <img width="0" height="0" src="http://dunnry.com/blog/aggbug.ashx?id=c83f5f74-9b35-4086-bafc-4c8388b572c7" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Where has all the bandwidth gone?</title>
    <link rel="alternate" type="text/html" href="http://dunnry.com/blog/WhereHasAllTheBandwidthGone.aspx" />
    <id>http://dunnry.com/blog/PermaLink,guid,596b528d-bf9a-4be7-a1de-edb02cfb7e21.aspx</id>
    <published>2008-06-01T17:26:38.0129948-04:00</published>
    <updated>2008-06-01T17:26:38.0129948-04:00</updated>
    <category term="Cloud Services" label="Cloud Services" scheme="http://dunnry.com/blog/CategoryView,category,Cloud%2BServices.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
According to <a href="http://www.akamai.com/stateoftheinternet/">a report</a> released
by Akamai (of CDN fame), Washington is the slowest state in the union when it comes
to broadband.  More appalling however is the USA's positioning with respect to
the rest of the world.  For the country that invented the internet (sorry Al),
we are sure a long way behind our European and Asian counterparts, ranking only 24th
for greater than 2Mbps broadband penetration.
</p>
        <p>
What is the problem here?  Why are we so far behind?  More troubling, why
has the cost of communication services like the internet access gone up year over
year with no appreciable increases in either service quality nor speed?  The
same cable companies that begged to be released from regulation - citing a free market
would increase competition and lower prices have instead <a href="http://www.signonsandiego.com/news/business/20050421-1450-adelphia-sale.html">consolidated</a>, <a href="http://www.latimes.com/technology/la-fi-hdtv27-2008may27,1,5954525.story">reduced
choice</a>, and <a href="http://www.nytimes.com/2008/05/24/technology/24cable.html">increased
rates</a>.
</p>
        <p>
Let's take a look at what speeds you typically get from your crappy cable provider. 
For an astonishing ~$50/month, you can order from your local cable provider a 6Mbps/768Kbps
package.  In some markets, you can order higher speed packages for significantly
higher rates.  Of course, in the markets that offer those higher speed tiers
you will likely run into a cap:
</p>
        <blockquote>
          <p>
An MSO talking 100 Mbit/s out of one side of its mouth and usage caps out the other
is like a bi-polar buffet restaurateur. They continue adding more entrees to an all-you-can-eat
spread, and then reduce the size of the plates and tell diners they only have 10 minutes
to chow. It's a recipe for dissatisfaction. The buffet looks bigger and tastier –
so the patron's hunger grows – and then they are asked to practice portion control. <a href="http://www.lightreading.com/document.asp?doc_id=144659&amp;site=cdn">[source]</a></p>
        </blockquote>
        <p>
Most people I know that have cable (all in fact) use the standard plan because the
higher speed plans are so much more expensive.  The plans have to be - if they
were cheap people would buy it and then the cable companies could never meet their
SLA for their customers.  So, let's deal with the average for now.
</p>
        <p>
The part that gets most people is that those bandwidth numbers provided by the cable
companies don't mean much in our every day surfing and downloading.  Quick, how
does 768Kbps in upload speed translate to your Bittorrent client on Comcast?[1] 
What is the max speed that you will be able to download the latest SP3 for XP on your
6Mbps connection?  Without doing the math, no one really knows - we are talking
two different units here.
</p>
        <p>
What most folks are used to seeing is the browser download progress window:
</p>
        <p>
          <a href="http://dunnry.com/blog/content/binary/WindowsLiveWriter/Wherehasallthebandwidthgone_C616/image_4.png">
            <img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="268" alt="image" src="http://dunnry.com/blog/content/binary/WindowsLiveWriter/Wherehasallthebandwidthgone_C616/image_thumb_1.png" width="374" border="0" />
          </a>
        </p>
        <p>
This measurement (usually in KB/s) is what most people can identify with to truly
understand how fast they can download something.  On a 6Mbps connection, your
theoretical max download speed is only 768KB/s.  Of course, no one but no one
gets that max speed.  It might burst in some markets for a bit, but with a huge
pipe coming down (like Microsoft Download Center), you are lucky if you get 400KB/s
max on most cable systems.
</p>
        <p>
An astute reader will notice that I am not using a normal cable provider here in the
screen shot.  In fact, at 1.24 MB/s, I am getting roughly 3x faster speeds that
'normal' cable.  This is because after suffering Comcast's incredibly slow and
laggy connection long enough, I bit the bullet and ordered FiOS from Verizon. 
I chose the 15Mbps/15Mbps package for roughly $70/month.  I am a heavy internet
user (both up and down) and so far it has been worth every penny.
</p>
        <p>
Here I am uploading all my MP3 collection to my backup provider (<a href="http://www.mozy.com">Mozy</a>). 
Previously on cable, I never dared doing it because I didn't want to tie up my connection
for a few weeks at the measly 40KB/s.  With FiOS, I can do this easily.
</p>
        <p>
          <a href="http://dunnry.com/blog/content/binary/WindowsLiveWriter/Wherehasallthebandwidthgone_C616/image_2.png">
            <img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="258" alt="image" src="http://dunnry.com/blog/content/binary/WindowsLiveWriter/Wherehasallthebandwidthgone_C616/image_thumb.png" width="414" border="0" />
          </a>
        </p>
        <p>
So what is the problem with the status quo?  Unless hordes of users start to
migrate to FiOS, cloud services in general will suffer for years to come.  The
value of a cloud service like Mozy is directly proportional to the bandwidth that
users can access to get to it.  Today, backing up only 30GB worth of data to
cloud storage at 40KB/s would take over <strong>9 days</strong>!  It is impractical
for most people to leave a machine on for 9 days and especially tie up all the bandwidth
in the house for the same period of time.  I know my parents would never do it.
</p>
        <p>
If we look at some of the more interesting cloud services that could be offered, we
see again that bandwidth (especially up) constrains the value of the service. 
Unfortunately, I don't hold out a lot of hope for things to improve soon.  Certain
classes of applications that could go in the cloud will be fine (web sites, some services,
and simple download only type services).  While truly interactive, rich media,
or game changing devices (imagine the <a href="http://www.nytimes.com/library/tech/99/09/biztech/articles/08sun.html">Network
PC</a>, but for real now) with be hobbled for years.  We'll see...
</p>
        <p>
What do you think?
</p>
        <p>
[1] Trick question: Comcast blocks Bittorrent, so it is likely 0 KB/s instead of the
theoretical 96 KB/s (max 40-50 KB/s in real use).
</p>
        <img width="0" height="0" src="http://dunnry.com/blog/aggbug.ashx?id=596b528d-bf9a-4be7-a1de-edb02cfb7e21" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Serialization in SSDS</title>
    <link rel="alternate" type="text/html" href="http://dunnry.com/blog/SerializationInSSDS.aspx" />
    <id>http://dunnry.com/blog/PermaLink,guid,d4fb7bdf-9f80-40de-adce-78cf43fb5158.aspx</id>
    <published>2008-05-28T15:06:03.9063948-04:00</published>
    <updated>2008-05-28T15:06:03.9063948-04:00</updated>
    <category term="Cloud Services" label="Cloud Services" scheme="http://dunnry.com/blog/CategoryView,category,Cloud%2BServices.aspx" />
    <category term="SSDS" label="SSDS" scheme="http://dunnry.com/blog/CategoryView,category,SSDS.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
SQL Server Data Services returns data in POX (plain ol' XML) format.  If you
look carefully at the way the data is returned, you can see that individual flex entities
look somewhat familiar to what is produced from the XmlSerializer.  I say 'somewhat'
because we have the data wrapped in this 'EntitySet' tag.
</p>
        <div>
          <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">s:EntitySet</span>
            <span style="color: #ff0000">xmlns:s</span>
            <span style="color: #0000ff">="http://schemas.microsoft.com/sitka/2008/03/"</span>
            <span style="color: #ff0000">xmlns:xsi</span>
            <span style="color: #0000ff">="http://www.w3.org/2001/XMLSchema-instance"</span>
            <span style="color: #ff0000">xmlns:x</span>
            <span style="color: #0000ff">="http://www.w3.org/2001/XMLSchema"</span>
            <span style="color: #0000ff">&gt;</span>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">PictureTag</span>
            <span style="color: #0000ff">&gt;</span>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">s:Id</span>
            <span style="color: #0000ff">&gt;</span>1e803f90-e5e5-4524-9e3c-3ba960be9494<span style="color: #0000ff">&lt;/</span><span style="color: #800000">s:Id</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">s:Version</span><span style="color: #0000ff">&gt;</span>1<span style="color: #0000ff">&lt;/</span><span style="color: #800000">s:Version</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">PictureId</span><span style="color: #ff0000">xsi:type</span><span style="color: #0000ff">="x:string"</span><span style="color: #0000ff">&gt;</span>3a1714bc-8771-4f6c-8d16-93238f126d9f<span style="color: #0000ff">&lt;/</span><span style="color: #800000">PictureId</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">TagId</span><span style="color: #ff0000">xsi:type</span><span style="color: #0000ff">="x:string"</span><span style="color: #0000ff">&gt;</span>ab696b85-1bdc-4bed-8824-dfbf9b67b5cc<span style="color: #0000ff">&lt;/</span><span style="color: #800000">TagId</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">PictureTag</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">s:EntitySet</span><span style="color: #0000ff">&gt;</span></pre>
        </div>
        <p>
I am using the PictureTag from the <a href="http://www.codeplex.com/phluffyfotos">PhluffyFotos</a> sample
application, but this could be any flexible entity.  If we extract the PictureTag
element and children from the surrounding EntitySet, we can very easily deserialize
this into a class.
</p>
        <p>
Given a class 'PictureTag':
</p>
        <div>
          <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
            <span style="color: #0000ff">public</span>
            <span style="color: #0000ff">class</span> PictureTag
{ [XmlElement(Namespace=<span style="color: #006080">"http://schemas.microsoft.com/sitka/2008/03/"</span>)] <span style="color: #0000ff">public</span><span style="color: #0000ff">string</span> Id
{ get; set; } [XmlElement(Namespace = <span style="color: #006080">"http://schemas.microsoft.com/sitka/2008/03/"</span>)] <span style="color: #0000ff">public</span><span style="color: #0000ff">int</span> Version
{ get; set; } <span style="color: #0000ff">public</span><span style="color: #0000ff">string</span> PictureId
{ get; set; } <span style="color: #0000ff">public</span><span style="color: #0000ff">string</span> TagId
{ get; set; } }</pre>
        </div>
        <p>
We can deserialize this class in just 3 lines of code:
</p>
        <div>
          <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
            <span style="color: #0000ff">string</span> xml
= <span style="color: #006080">@"&lt;s:EntitySet xmlns:s="</span><span style="color: #006080">"http://schemas.microsoft.com/sitka/2008/03/"</span><span style="color: #006080">"
xmlns:xsi="</span><span style="color: #006080">"http://www.w3.org/2001/XMLSchema-instance"</span><span style="color: #006080">"
xmlns:x="</span><span style="color: #006080">"http://www.w3.org/2001/XMLSchema"</span><span style="color: #006080">"&gt;
&lt;PictureTag&gt; &lt;s:Id&gt;1e803f90-e5e5-4524-9e3c-3ba960be9494&lt;/s:Id&gt; &lt;s:Version&gt;1&lt;/s:Version&gt;
&lt;PictureId xsi:type="</span><span style="color: #006080">"x:string"</span><span style="color: #006080">"&gt;3a1714bc-8771-4f6c-8d16-93238f126d9f&lt;/PictureId&gt;
&lt;TagId xsi:type="</span><span style="color: #006080">"x:string"</span><span style="color: #006080">"&gt;ab696b85-1bdc-4bed-8824-dfbf9b67b5cc&lt;/TagId&gt;
&lt;/PictureTag&gt; &lt;/s:EntitySet&gt;"</span>; var xmlTag = XElement.Parse(xml).Element(<span style="color: #006080">"PictureTag"</span>);
XmlSerializer xs = <span style="color: #0000ff">new</span> XmlSerializer(<span style="color: #0000ff">typeof</span>(PictureTag));
var tag = (PictureTag)xs.Deserialize(xmlTag.CreateReader());</pre>
        </div>
        <p>
Now, the 'tag' variable is a PictureTag instance.  As you can see, deserialization
is a snap.  What about serialization, however?
</p>
        <p>
If I reverse the process using the following code, you will notice that something
has changed:
</p>
        <div>
          <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
            <span style="color: #0000ff">using</span> (var
ms = <span style="color: #0000ff">new</span> MemoryStream()) { <span style="color: #008000">//add
a bunch of namespaces and override the default ones too</span> XmlSerializerNamespaces
namespaces = <span style="color: #0000ff">new</span> XmlSerializerNamespaces(); namespaces.Add(<span style="color: #006080">"s"</span>, <span style="color: #006080">@"http://schemas.microsoft.com/sitka/2008/03/"</span>);
namespaces.Add(<span style="color: #006080">"x"</span>, <span style="color: #006080">@"http://www.w3.org/2001/XMLSchema"</span>);
namespaces.Add(<span style="color: #006080">"xsi"</span>, <span style="color: #006080">@"http://www.w3.org/2001/XMLSchema-instance"</span>);
XmlWriterSettings xws = <span style="color: #0000ff">new</span> XmlWriterSettings();
xws.Indent = <span style="color: #0000ff">true</span>; xws.OmitXmlDeclaration = <span style="color: #0000ff">true</span>; <span style="color: #0000ff">using</span> (XmlWriter
writer = XmlWriter.Create(ms, xws)) { xs.Serialize(writer, tag, namespaces); ms.Position
= 0; <span style="color: #008000">//reset to beginning</span><span style="color: #0000ff">using</span> (var
sr = <span style="color: #0000ff">new</span> StreamReader(ms)) { xmlTag = XElement.Parse(sr.ReadToEnd());
} } }</pre>
        </div>
        <p>
If I look in the 'xmlTag' XElement, I get somewhat different XML back:
</p>
        <div>
          <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">PictureTag</span>
            <span style="color: #ff0000">xmlns:s</span>
            <span style="color: #0000ff">="http://schemas.microsoft.com/sitka/2008/03/"</span>
            <span style="color: #ff0000">xmlns:xsi</span>
            <span style="color: #0000ff">="http://www.w3.org/2001/XMLSchema-instance"</span>
            <span style="color: #ff0000">xmlns:x</span>
            <span style="color: #0000ff">="http://www.w3.org/2001/XMLSchema"</span>
            <span style="color: #0000ff">&gt;</span>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">s:Id</span>
            <span style="color: #0000ff">&gt;</span>1e803f90-e5e5-4524-9e3c-3ba960be9494<span style="color: #0000ff">&lt;/</span><span style="color: #800000">s:Id</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">s:Version</span><span style="color: #0000ff">&gt;</span>1<span style="color: #0000ff">&lt;/</span><span style="color: #800000">s:Version</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">PictureId</span><span style="color: #0000ff">&gt;</span>3a1714bc-8771-4f6c-8d16-93238f126d9f<span style="color: #0000ff">&lt;/</span><span style="color: #800000">PictureId</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">TagId</span><span style="color: #0000ff">&gt;</span>ab696b85-1bdc-4bed-8824-dfbf9b67b5cc<span style="color: #0000ff">&lt;/</span><span style="color: #800000">TagId</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">PictureTag</span><span style="color: #0000ff">&gt;</span></pre>
        </div>
        <p>
I lost the 'xsi:type' attributes that I need in order to signal to SSDS how to treat
the type.  Bummer.
</p>
        <p>
We can manually add the attributes (fix-up) after the serialization.  Let's see
how that would work:
</p>
        <div>
          <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">XNamespace xsi = <span style="color: #006080">@"http://www.w3.org/2001/XMLSchema-instance"</span>;
XNamespace ns = <span style="color: #006080">@"http://schemas.microsoft.com/sitka/2008/03/"</span>; <span style="color: #008000">//xmlTag
is XElement holding our</span> var nodes = xmlTag.Descendants(); <span style="color: #0000ff">foreach</span> (var
node <span style="color: #0000ff">in</span> nodes) { <span style="color: #0000ff">if</span> (node.Name
!= (ns + <span style="color: #006080">"Id"</span>) &amp;&amp; node.Name != (ns + <span style="color: #006080">"Version"</span>))
{ node.Add( <span style="color: #0000ff">new</span> XAttribute( xsi + <span style="color: #006080">"type"</span>,
GetAttributeType(node.Name.LocalName.ToString(), <span style="color: #0000ff">typeof</span>(PictureTag))
) ); } }</pre>
        </div>
        <p>
We need to loop through each node and set the 'xsi:type' attribute appropriately. 
Here is my quick and dirty implementation: 
</p>
        <div>
          <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
            <span style="color: #0000ff">static</span> Dictionary&lt;Type, <span style="color: #0000ff">string</span>&gt;
xsdTypes = <span style="color: #0000ff">new</span> Dictionary&lt;Type, <span style="color: #0000ff">string</span>&gt;()
{ {<span style="color: #0000ff">typeof</span>(<span style="color: #0000ff">string</span>), <span style="color: #006080">"x:string"</span>},
{<span style="color: #0000ff">typeof</span>(<span style="color: #0000ff">int</span>), <span style="color: #006080">"x:decimal"</span>},
{<span style="color: #0000ff">typeof</span>(<span style="color: #0000ff">long</span>), <span style="color: #006080">"x:decimal"</span>},
{<span style="color: #0000ff">typeof</span>(<span style="color: #0000ff">float</span>), <span style="color: #006080">"x:decimal"</span>},
{<span style="color: #0000ff">typeof</span>(<span style="color: #0000ff">decimal</span>), <span style="color: #006080">"x:decimal"</span>},
{<span style="color: #0000ff">typeof</span>(<span style="color: #0000ff">short</span>), <span style="color: #006080">"x:decimal"</span>},
{<span style="color: #0000ff">typeof</span>(DateTime), <span style="color: #006080">"x:dateTime"</span>},
{<span style="color: #0000ff">typeof</span>(<span style="color: #0000ff">bool</span>), <span style="color: #006080">"x:boolean"</span>},
{<span style="color: #0000ff">typeof</span>(<span style="color: #0000ff">byte</span>[]), <span style="color: #006080">"x:base64Binary"</span>}
}; <span style="color: #0000ff">private</span><span style="color: #0000ff">static</span><span style="color: #0000ff">string</span> GetAttributeType(<span style="color: #0000ff">string</span> name,
Type type) { var prop = type.GetProperty(name); <span style="color: #0000ff">if</span> (prop
!= <span style="color: #0000ff">null</span>) { <span style="color: #0000ff">if</span> (xsdTypes.ContainsKey(prop.PropertyType)) <span style="color: #0000ff">return</span> xsdTypes[prop.PropertyType];
} <span style="color: #0000ff">return</span> xsdTypes[<span style="color: #0000ff">typeof</span>(<span style="color: #0000ff">string</span>)];
}</pre>
        </div>
        <p>
When all is said and done, I am back to what I need:
</p>
        <div>
          <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">PictureTag</span>
            <span style="color: #ff0000">xmlns:s</span>
            <span style="color: #0000ff">="http://schemas.microsoft.com/sitka/2008/03/"</span>
            <span style="color: #ff0000">xmlns:xsi</span>
            <span style="color: #0000ff">="http://www.w3.org/2001/XMLSchema-instance"</span>
            <span style="color: #ff0000">xmlns:x</span>
            <span style="color: #0000ff">="http://www.w3.org/2001/XMLSchema"</span>
            <span style="color: #0000ff">&gt;</span>
            <span style="color: #0000ff">&lt;</span>
            <span style="color: #800000">s:Id</span>
            <span style="color: #0000ff">&gt;</span>1e803f90-e5e5-4524-9e3c-3ba960be9494<span style="color: #0000ff">&lt;/</span><span style="color: #800000">s:Id</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">s:Version</span><span style="color: #0000ff">&gt;</span>1<span style="color: #0000ff">&lt;/</span><span style="color: #800000">s:Version</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">PictureId</span><span style="color: #ff0000">xsi:type</span><span style="color: #0000ff">="x:string"</span><span style="color: #0000ff">&gt;</span>3a1714bc-8771-4f6c-8d16-93238f126d9f<span style="color: #0000ff">&lt;/</span><span style="color: #800000">PictureId</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">TagId</span><span style="color: #ff0000">xsi:type</span><span style="color: #0000ff">="x:string"</span><span style="color: #0000ff">&gt;</span>ab696b85-1bdc-4bed-8824-dfbf9b67b5cc<span style="color: #0000ff">&lt;/</span><span style="color: #800000">TagId</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">PictureTag</span><span style="color: #0000ff">&gt;</span></pre>
        </div>
        <p>
However, I am not sure I really like this technique.  It seems like that if I
am going to be using Reflection to 'fix-up' the XML from the XmlSerializer, I might
as well just use it to build the entire thing.  With that in mind, here is the
next implementation of SSDS Serialization:
</p>
        <div>
          <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
            <span style="color: #0000ff">public</span>
            <span style="color: #0000ff">static</span> XElement
CreateEntity&lt;T&gt;(T instance, <span style="color: #0000ff">string</span> id) <span style="color: #0000ff">where</span> T
: <span style="color: #0000ff">class</span>, <span style="color: #0000ff">new</span>()
{ XNamespace ns = <span style="color: #006080">@"http://schemas.microsoft.com/sitka/2008/03/"</span>;
XNamespace xsi = <span style="color: #006080">@"http://www.w3.org/2001/XMLSchema-instance"</span>;
XNamespace x = <span style="color: #006080">@"http://www.w3.org/2001/XMLSchema"</span>; <span style="color: #0000ff">if</span> (instance
== <span style="color: #0000ff">null</span>) <span style="color: #0000ff">return</span><span style="color: #0000ff">null</span>; <span style="color: #0000ff">if</span> (String.IsNullOrEmpty(id)) <span style="color: #0000ff">throw</span><span style="color: #0000ff">new</span> ArgumentNullException(<span style="color: #006080">"id"</span>);
Type type = <span style="color: #0000ff">typeof</span>(T); <span style="color: #008000">//
Create an element for each non-system, non-binary property on the class</span> var
properties = from p <span style="color: #0000ff">in</span> type.GetProperties() <span style="color: #0000ff">where</span> xsdTypes.ContainsKey(p.PropertyType)
&amp;&amp; p.Name != <span style="color: #006080">"Id"</span> &amp;&amp; p.Name != <span style="color: #006080">"Version"</span> &amp;&amp;
!p.PropertyType.Equals(<span style="color: #0000ff">typeof</span>(<span style="color: #0000ff">byte</span>[]))
select <span style="color: #0000ff">new</span> XElement(p.Name, <span style="color: #0000ff">new</span> XAttribute(xsi
+ <span style="color: #006080">"type"</span>, xsdTypes[p.PropertyType]), p.GetValue(instance, <span style="color: #0000ff">null</span>)
); <span style="color: #008000">// Binary properties are special, since they must
be serialized as Base-64</span> var binaryProperties = from p <span style="color: #0000ff">in</span> type.GetProperties() <span style="color: #0000ff">where</span> p.PropertyType.Equals(<span style="color: #0000ff">typeof</span>(<span style="color: #0000ff">byte</span>[]))
&amp;&amp; (p.GetValue(instance, <span style="color: #0000ff">null</span>) != <span style="color: #0000ff">null</span>)
select <span style="color: #0000ff">new</span> XElement(p.Name, <span style="color: #0000ff">new</span> XAttribute(xsi
+ <span style="color: #006080">"type"</span>, xsdTypes[p.PropertyType]), Convert.ToBase64String((<span style="color: #0000ff">byte</span>[])p.GetValue(instance, <span style="color: #0000ff">null</span>))
); <span style="color: #008000">// Construct the Xml</span> var xml = <span style="color: #0000ff">new</span> XElement(type.Name, <span style="color: #0000ff">new</span> XElement(ns
+ <span style="color: #006080">"Id"</span>, id), <span style="color: #008000">//here
is the Id element</span><span style="color: #0000ff">new</span> XAttribute(XNamespace.Xmlns
+ <span style="color: #006080">"s"</span>, ns), <span style="color: #0000ff">new</span> XAttribute(XNamespace.Xmlns
+ <span style="color: #006080">"xsi"</span>, xsi), <span style="color: #0000ff">new</span> XAttribute(XNamespace.Xmlns
+ <span style="color: #006080">"x"</span>, x), properties, binaryProperties ); <span style="color: #0000ff">return</span> xml;
}</pre>
        </div>
        <p>
In this case, we are using Reflection to build a list of Properties in the object
and depending on the type (byte[] array is special), we build the XElement ourselves
and assemble the entity by hand.  We can use it like this:
</p>
        <div>
          <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">XElement entity = CreateEntity&lt;PictureTag&gt;(tag, tag.Id);</pre>
        </div>
        <p>
Of course, there are a number of other techniques that I am not covering in this already
very long post.  Perhaps in my next post we will look at a few others.
</p>
        <img width="0" height="0" src="http://dunnry.com/blog/aggbug.ashx?id=d4fb7bdf-9f80-40de-adce-78cf43fb5158" />
      </div>
    </content>
  </entry>
  <entry>
    <title>The Business Value of SQL Server Data Services</title>
    <link rel="alternate" type="text/html" href="http://dunnry.com/blog/TheBusinessValueOfSQLServerDataServices.aspx" />
    <id>http://dunnry.com/blog/PermaLink,guid,8466ac02-81fb-4b2f-aff9-4b35a8a49d70.aspx</id>
    <published>2008-05-07T17:04:50.3763148-04:00</published>
    <updated>2008-05-07T17:04:50.3763148-04:00</updated>
    <category term="Cloud Services" label="Cloud Services" scheme="http://dunnry.com/blog/CategoryView,category,Cloud%2BServices.aspx" />
    <category term="SSDS" label="SSDS" scheme="http://dunnry.com/blog/CategoryView,category,SSDS.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
In my second video of a planned series of videos (number yet to be determined), I
interviewed Tudor Toma, Group Program Manager and Soumitra Sengupta, SSDS Architect
about the business value of SSDS.
</p>
        <p>
          <a href="http://channel9.msdn.com/ShowPost.aspx?PostID=401696">Watch the Video</a>
        </p>
        <p>
One point that I want to emphasize is that from a business perspective, SSDS tackles
two of the biggest pain points that companies have to deal with today when creating
new IT systems:  capital expenditures (CapEx) and operational expenditures (OpEx). 
Beyond just the dollar cost of how much software costs to create, you need to think
about how much hardware or hosting will cost.  You have to plan capacity and
guess the load the system will generate.  Next, you have to figure out how many
support personnel will be required to maintain the system.  Someone has to maintain
the software, repair machines when they go down, defrag, patch, update, etc.
</p>
        <p>
One of the greatest business values (as opposed to technical values) you get from
SSDS (and cloud services in general) is the ability to redeploy the capital to other
resources.  In the case of CapEx, you can deploy this perhaps to marketing or
content creation.  In the case of OpEx, those expenses can be redeployed to more
useful tasks in the enterprise (creating new systems, upgrading, and expanding operations
perhaps?).  While there are opportunities to just save this money, I think more
realistically the money is going to get spent on the other things that you wished
you had time and resources for.
</p>
        <p>
I think the value is easy to understand from a startup's perspective.  But even
enterprise users should be thinking about this.  Big budget IT programs could
easily be switched out to cloud services at a fraction of the cost to build out the
support and infrastructure needs.  Money that would otherwise be spent for disaster
recovery (you do DR planning, right?) can be re-purposed or saved.  The days
of multi-million dollar new IT investments are numbered in a lot of cases in my opinion. 
I can still see a few cases where it would be necessary depending on a companies core
value proposition, but for a majority, it just doesn't make sense.
</p>
        <img width="0" height="0" src="http://dunnry.com/blog/aggbug.ashx?id=8466ac02-81fb-4b2f-aff9-4b35a8a49d70" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Amazon MP3 Downloader</title>
    <link rel="alternate" type="text/html" href="http://dunnry.com/blog/AmazonMP3Downloader.aspx" />
    <id>http://dunnry.com/blog/PermaLink,guid,c72f247b-5179-44e8-958e-3e2d45881c3c.aspx</id>
    <published>2008-04-27T20:45:53.5988948-04:00</published>
    <updated>2008-04-27T20:45:53.5988948-04:00</updated>
    <category term="Digital Rights" label="Digital Rights" scheme="http://dunnry.com/blog/CategoryView,category,Digital%2BRights.aspx" />
    <category term="Personal" label="Personal" scheme="http://dunnry.com/blog/CategoryView,category,Personal.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
I just tried out the new Amazon MP3 store and the accompanying MP3 downloader. 
So far, it seems like a nice piece of unobtrusive software (unlike that evil, evil
iTunes POS).  Although <a href="http://dunnry.com/blog/AmazonUnboxesCrap.aspx">I
was not a fan</a> of the Unbox service, I think I have found where I will be downloading
music from now on...
</p>
        <img width="0" height="0" src="http://dunnry.com/blog/aggbug.ashx?id=c72f247b-5179-44e8-958e-3e2d45881c3c" />
      </div>
    </content>
  </entry>
  <entry>
    <title>My Comcastic Reaming Adventure</title>
    <link rel="alternate" type="text/html" href="http://dunnry.com/blog/MyComcasticReamingAdventure.aspx" />
    <id>http://dunnry.com/blog/PermaLink,guid,6c94cefa-1efd-4f0f-aa94-74eaf4e213b8.aspx</id>
    <published>2008-04-12T17:56:12.4989698-04:00</published>
    <updated>2008-05-19T19:12:23.8682498-04:00</updated>
    <category term="Personal" label="Personal" scheme="http://dunnry.com/blog/CategoryView,category,Personal.aspx" />
    <category term="Rants" label="Rants" scheme="http://dunnry.com/blog/CategoryView,category,Rants.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
I recently moved and had to get Comcast.  Is there any other business entity
in the world that is so despised as cable companies?  The RIAA is close, but
you are much more likely to deal with cable companies than the prior.  Warning:
ranting to follow...
</p>
        <h3>Part I: Ordering
</h3>
        <p>
Calling Comcast to order packages found on comcast.com is an exercise in futility. 
First, the rep will spend 20 minutes trying to upsell you to their damn $99 triple
play bundle.  My favorite part of that experience:  If you tell them you
are not interested in the phone service (I am not) and you use the word VOIP, they
will correct you: "<em>no, no... it is not *VOIP* sir, it is *secure* voice communication
over your cable line</em>".  Ahh... I forgot that Comcast sells magic flippin'
fairy dust that makes the IP packets carrying your voice a.) turn magically secure,
and b.) not be called IP packets.
</p>
        <p>
I didn't bother correcting her as I realized she was just a script-reading monkey
making commissions on selling Triple Play.  After firmly insisting that no, I
really didn't want magic non-VOIP, 'secure', VOIP communication, I asked what the
price of basic cable was.  I was told it was something like $53 for just basic
cable.  Note, you cannot find this price on the website, you can only find the
price of bundles.  I tell her that I know for a fact that people can get cable
for $20 or so and she tells me, "<em>oh, you want *limited* cable!, yes that's $20</em>". 
She then proceeds to tell me that you can either have limited for $20 or what they
call the "Digital Starter Pack" for $53.  I tell her that Comcast's website says
that there is a package in between called "Basic", and she denies it.  Perhaps
they should fix their (censored) website:
</p>
        <p>
 
</p>
        <p>
          <a href="http://dunnry.com/blog/content/binary/WindowsLiveWriter/MyComcasticReamingAdventure_C9C1/image_4.png">
            <img alt="image" src="http://dunnry.com/blog/content/binary/WindowsLiveWriter/MyComcasticReamingAdventure_C9C1/image_4.png" />
          </a>
        </p>
        <p>
So, at this point she is just lying to me and I know it, so I decide to test her a
bit.  I ask her about adding internet to the package and bundling the price. 
She tells me that is the $53 + $43 or $96 a month and that there is no bundle for
that.  She then mentions that the triple play would be a better deal at $99 with
more channels (plus phone!!).  I love it when the $8/hr. help tries to treat
me like a retarded cave man.
</p>
        <p>
I point out that the a.) the internet is $20/month on the website and b.) internet
+ cable on the website is only $60 a month there as well.  She tells me that
it is a special deal only through the web.  So, I press the point:  "are
you telling me that you do not offer a "Double Play" bundle like the website, but
you *do* offer the same "Triple Play" bundle as the website?  Do you or do you
not sell a Double Play option?"
</p>
        <p>
The truth slowly bubbles to the surface.  It turns out yes, they do offer a internet
+ cable bundle called "Double Play" she corrects herself, but it is $70 a month, not
$60.  I ask her why she told me $96.  She tells me she thought I wanted
only basic (Digital Starter cable), while the "Double Play" version she sells includes
"Digital Preferred" or Premier, I forget.  So in essence, she was willing to
sell me an inferior package for more money than admit there was a bundle that offered
more for less money to prove her point that I should be buying the (censored) Triple
Play still.  She still won't admit there is a "Basic" cable tier between Limited
and Digital Starter either.
</p>
        <p>
I end up telling her that I will order through the website since she can't even sell
me the same things that are being offered and she hasn't been entirely forthcoming
with me.
</p>
        <h3>Part II:  The Installation
</h3>
        <p>
After ordering the $60 Double Play bundle including a nice $45 charge to "install"
the cable, I confirm online that I want the HD equipment and 2 boxes for my two HD
capable TVs.  The technicians (contractors) show up on Saturday (1 week ago)
and guess what they don't bring?  If you said HD boxes... you're right!
</p>
        <p>
After calling support while the contractors were there, the support rep tells me that
she will add the HD equipment to the account and that she will call me back. 
I tell her I want the fee waived since the install is botched - she agrees to waive
the fee (yeah!).  Guess what happens?  If you said, "she won't add the boxes
and totally will not call you back and will not waive fee"... you're right!
</p>
        <p>
So, after dickering around a bit, I get the contractors to give me an 'extra' HD box
they have in their truck and they call and get it added to my account.  Then,
they tell me that I will have to drive to the store to get another HD box and "later
man", they are gone.  At no point did they actually test to make sure that I
was getting the programming package that I paid for.  So, guess what happens? 
If you said, "Ryan won't get any of the channels he paid for"...  you're right!
</p>
        <h3>Part III:  The Cleanup
</h3>
        <p>
So, after 1 day I notice that I don't have many channels... in fact I have very few
channels.  I start an online chat to get those turned on.  The rep there
can't get them on despite "sending a signal to the box".  He schedules a technician
visit for me.  I explicitly ask for three things (I have this in a transcript):
a.) my channels turned on, b.) the missing HD equipment with firewire output for my
media center, and c.) to waive the service charge since this a botched thing on their
part.  He agrees on all three things and tells me they will be there tomorrow
between 8am and 12pm.
</p>
        <p>
I wake bright and early on Monday in case they decide to show exactly at 8am. 
I realize of course that if I am ready at 8am they won't show until 12pm, but if I
am not ready at 8am you can bet that will be when they show up according to Murphy's
Law.  Around 11:20am I decide to give Comcast a call to confirm the scheduled
visit.  Turns out that the previous rep left no notes to why I called and that
they were not going to send anyone.  One emergency page later, I have a Comcast
technician showing up exactly at 12pm.  He admits he has no idea why he is there
however and asks me what he can do.
</p>
        <p>
The only bright part in this entire story is that technician.  He was a nice,
competent guy that actually got things done.  He determined that they had just
botched configuring the box back at the main office.  A few phone calls later,
my box is turned on and channels are fixed.  Next, he happens to have the HD
box I need, so he hooks me up there.  He apologizes to me and admits that none
of this should have happened and that it could all have been easily fixed on the first
attempt.  All in all, I think I am done with this tragedy.
</p>
        <h3>Part IV:  The Lingering Stink
</h3>
        <p>
Today, I got my Comcast bill.  Guess what?  If you guessed that I would
be charged not only for the first $45 botched install, plus the second $20 install
to fix the first and would be facing a $150 cable bill for &lt; 7 days service...
you're right!
</p>
        <p>
So, today I decide to email them through the Comcast website and see what gets resolved. 
I explain nicely and in detail what has occurred to this point and try to submit. 
Of course, nowhere does it explain there is a limit to how much you can email (side
note, I forgot that most email systems choke up under 4 paragraphs of text these days). 
So, many shortened revisions later, I try to submit my story for resolution and here
is what I get:
</p>
        <p>
          <a href="http://dunnry.com/blog/content/binary/WindowsLiveWriter/MyComcasticReamingAdventure_C9C1/image_2.png">
            <img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="125" alt="image" src="http://dunnry.com/blog/content/binary/WindowsLiveWriter/MyComcasticReamingAdventure_C9C1/image_2.png" width="562" border="0" />
          </a>
        </p>
        <p>
My comcastic adventure is just getting better and better.  Naturally, I decide
to look up "comcastic" to see what the actual definition is:
</p>
        <blockquote>
          <p>
            <strong>comcastic</strong> (adj.)
</p>
          <p>
1. A blithe attempt to screw consumers.  "The comcastic enterprise left few consumers
happy with the reduced service higher prices, and hidden charges".
</p>
          <p>
2. Lacking follow through or resolve.  "That fat lazy bastard approached his
work like he did exercise:  with comcastic resolve."
</p>
          <p>
synonyms: see <strong>LIARS, UNRELIABLE, CRAPTACULAR, PRISON SEX</strong></p>
        </blockquote>
        <p>
Turns out that is was my fault for not checking the dictionary first when I was told
that my experience would be "comcastic".
</p>
        <img width="0" height="0" src="http://dunnry.com/blog/aggbug.ashx?id=6c94cefa-1efd-4f0f-aa94-74eaf4e213b8" />
      </div>
    </content>
  </entry>
  <entry>
    <title>PhluffyFotos Sample Available</title>
    <link rel="alternate" type="text/html" href="http://dunnry.com/blog/PhluffyFotosSampleAvailable.aspx" />
    <id>http://dunnry.com/blog/PermaLink,guid,6d66af42-11f1-4b07-a4a6-ab83fa44be0a.aspx</id>
    <published>2008-04-09T15:02:37.097728-04:00</published>
    <updated>2008-04-09T15:02:37.097728-04:00</updated>
    <category term=".NET" label=".NET" scheme="http://dunnry.com/blog/CategoryView,category,.NET.aspx" />
    <category term="Cloud Services" label="Cloud Services" scheme="http://dunnry.com/blog/CategoryView,category,Cloud%2BServices.aspx" />
    <category term="SSDS" label="SSDS" scheme="http://dunnry.com/blog/CategoryView,category,SSDS.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
I just posted the first version of <a href="http://www.codeplex.com/phluffyfotos">PhluffyFotos</a>,
our SQL Server Data Services (SSDS) sample app to CodePlex.  PhluffyFotos is
a photo sharing site that allows users to upload photos and metadata (tags, description)
to SSDS for storage.  As the service gets more features and is updated, the sample
will be rev'd as well.
</p>
        <p>
Points of interest that will likely also be blog posts in themselves:
</p>
        <ul>
          <li>
This sample has a LINQ-to-SSDS provider in it.  You will notice we don't use
any strings for queries, but rather lambda expressions.  I had a lot of fun writing
the first version of this and I would expect that there are a few more revisions here
to go.  Of course, <a href="http://blogs.msdn.com/mattwar/archive/2007/07/30/linq-building-an-iqueryable-provider-part-i.aspx">Matt
Warren</a> should get a ton of credit here for providing the base implementation.</li>
          <li>
This sample also uses a very simplistic ASP.NET Role provider for SSDS.  Likely
updates here will include encryption and hashing support.</li>
          <li>
We have a number of Powershell cmdlets included for managing authorities and containers.</li>
        </ul>
        <p>
I have many other ideas for this app as time progresses, so you should check back
from time to time to see the updates.
</p>
        <p>
In case anyone was wondering about the name: clouds are fluffy... get it?
</p>
        <p>
          <strong>
            <em>You need to have SSDS credentials to run this sample.  If you don't
have credentials yet, you can see an online version until then at <a href="http://www.phluffyfotos.com">http://www.phluffyfotos.com</a></em>
          </strong>
        </p>
        <p>
Even if you don' t have access to SSDS credentials yet, the code is worth taking a
look.
</p>
        <img width="0" height="0" src="http://dunnry.com/blog/aggbug.ashx?id=6d66af42-11f1-4b07-a4a6-ab83fa44be0a" />
      </div>
    </content>
  </entry>
  <entry>
    <title>SSDS Architecture Interview</title>
    <link rel="alternate" type="text/html" href="http://dunnry.com/blog/SSDSArchitectureInterview.aspx" />
    <id>http://dunnry.com/blog/PermaLink,guid,0257442e-2d83-4857-baa6-6c058ca61620.aspx</id>
    <published>2008-04-07T16:30:49.467363-04:00</published>
    <updated>2008-04-07T16:30:49.467363-04:00</updated>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
I had the chance recently to sit down and interview two of the senior architects on
the SQL Server Data Services team.  Istvan and Nigel were good sports for the
interview (my first for Channel9).  Afterwards, of course I thought to myself,
"man, I should have asked them X or Y" - however I will be doing more of these types
of interviews, so I can redeem myself hopefully.  If there is a particular question
you would like me to pose to the team, drop me a line and let me know.
</p>
        <p>
          <a href="http://channel9.msdn.com/ShowPost.aspx?PostID=395843">Video Link</a>
        </p>
        <img width="0" height="0" src="http://dunnry.com/blog/aggbug.ashx?id=0257442e-2d83-4857-baa6-6c058ca61620" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Interested in SQL Server Data Services?</title>
    <link rel="alternate" type="text/html" href="http://dunnry.com/blog/InterestedInSQLServerDataServices.aspx" />
    <id>http://dunnry.com/blog/PermaLink,guid,68319a66-7967-4e9d-a87b-000adec09175.aspx</id>
    <published>2008-03-31T18:13:27.675048-04:00</published>
    <updated>2008-03-31T18:13:27.675048-04:00</updated>
    <category term="Cloud Services" label="Cloud Services" scheme="http://dunnry.com/blog/CategoryView,category,Cloud%2BServices.aspx" />
    <category term="SSDS" label="SSDS" scheme="http://dunnry.com/blog/CategoryView,category,SSDS.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
Are you a Ruby on Rails (RoR) shop?  PHP shop?  Java shop? Are you a web
startup using open source technologies to build your services?
</p>
        <p>
Great news,  we have a limited number of seats available for folks like you to
get firsthand exposure to our new HTTP-based (SOAP and REST) data service:  SQL
Server Data Services (SSDS).  You will get early access to the service and the
chance to influence the service itself.
</p>
        <p>
We are interested in getting some feedback from people like you that don't necessarily
use Microsoft technologies.  If you can connect using HTTP, you can use SSDS,
so there are very few client limitations here.
</p>
        <h3>How to get involved
</h3>
        <p>
If you are one of those non-.NET developers that sees value in utility storage and
query processing, send me an email to <strong>dpesdr (AT) microsoft.com</strong>.
</p>
        <p>
In your email, please tell me <strong>about your company</strong> and <strong>about
your product </strong>where you think SSDS might fit.  We will review your email
and follow up with more information.
</p>
        <h3>Details
</h3>
        <p>
When: <strong>April 24-25th, 2008</strong><br />
Where:  <a href="http://www.microsoft.com/about/companyinformation/usaoffices/northernca/svc.mspx">Microsoft
Silicon Valley Campus</a> 
</p>
        <h3>Cost
</h3>
        <p>
This is a free event but seating is limited - <strong><u>you must have a confirmed
reservation to attend this event</u></strong>.  Attendees are responsible for
any transportation or lodging costs.  Microsoft will provide breakfast, lunch,
and light snacks during the event.  You are responsible for your own dinner expenses.
</p>
        <h3>About SQL Server Data Services
</h3>
        <p>
SQL Server Data Services (SSDS) is a highly scalable web facing data storage and query
processing utility. Built on robust SQL Server database technology, these services
provide high availability and security and support standards-based web protocols and
interfaces (SOAP, REST) for rapid provisioning and ease of programming. Businesses
can store and access all types of data from birth to archival and sers can access
information on any device, from the desktop to a mobile device.
</p>
        <h3>Key Features and Solution Benefits 
</h3>
        <p>
Application Agility for quick deployment<br />
•    Internet standard protocols and Interfaces (REST, SOAP).<br />
•    Flexible data model with no schema required.<br />
•    Simple text base query model.<br />
•    Easy to program to from any programming environment.<br />
On-Demand Scalability<br />
•    Easy storage and access. Pay as you grow model.<br />
•    Scales as data grows.<br />
•    Web services for provisioning, deployment, and monitoring.<br />
Business-Ready SLA<br />
•    Built on robust Microsoft SQL Server database and Windows server
technologies.<br />
•    Store and manage multiple copies of the data for reliability and
availability.<br />
•    Back up data stored in each data cluster. Geo-redundant data copies
to ensure business continuity.<br />
•    Secure data access to help provide business confidentiality and
privacy.
</p>
        <img width="0" height="0" src="http://dunnry.com/blog/aggbug.ashx?id=68319a66-7967-4e9d-a87b-000adec09175" />
      </div>
    </content>
  </entry>
  <entry>
    <title>SSDS Query Model</title>
    <link rel="alternate" type="text/html" href="http://dunnry.com/blog/SSDSQueryModel.aspx" />
    <id>http://dunnry.com/blog/PermaLink,guid,39a97ebb-780d-4992-bb78-f472f5e58106.aspx</id>
    <published>2008-03-13T13:48:23.853463-04:00</published>
    <updated>2008-03-13T13:48:23.853463-04:00</updated>
    <category term="Cloud Services" label="Cloud Services" scheme="http://dunnry.com/blog/CategoryView,category,Cloud%2BServices.aspx" />
    <category term="SSDS" label="SSDS" scheme="http://dunnry.com/blog/CategoryView,category,SSDS.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <strong>Note:</strong> The query model is subject to change based on feedback; this
is how it stands today.  You can pre-register for the beta at the <a href="http://www.microsoft.com/sql/dataservices">SSDS
home page</a>.
</p>
        <h2>Design Decisions
</h2>
        <p>
In this post, I am going to cover how the query model works in SQL Server Data Services
(SSDS) today and some of the design goals of SSDS in general.
</p>
        <p>
The first thing to understand is that the SSDS team made a conscious decision to start
simple and expand functionality later.  The reasoning behind this is simple:
</p>
        <ul>
          <li>
Simple services that lower the bar to get started are easier to adopt.  We want
to offer the smallest useful feature set that developers can start using to build
applications. 
</li>
          <li>
At the same time, we want to make sure that every feature that is available will scale
appropriately at internet-level. 
</li>
        </ul>
        <p>
As such, the right model is what the team chose:  start simple and expose richer
and richer functionality as we prove out the scale and developer's need.  The
team is committed to short (8 week) development cycles that prioritizes the features
based on feedback.
</p>
        <h2>The Query Model
</h2>
        <p>
Now that I have covered the design decisions, let's take a look at how the query model
actually o