<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://mtaulty.com/CommunityServer/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Mike Taulty's Blog</title><link>http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/default.aspx</link><description>Bits and Bytes</description><dc:language>en-GB</dc:language><generator>CommunityServer 2.0 (Build: 60217.2664)</generator><item><title>Outrageous Self-Promotion :-)</title><link>http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2008/07/03/10572.aspx</link><pubDate>Thu, 03 Jul 2008 22:29:42 GMT</pubDate><guid isPermaLink="false">c62f47b3-9054-4265-9c0c-549d811810c2:10572</guid><dc:creator>mtaulty</dc:creator><slash:comments>0</slash:comments><comments>http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/comments/10572.aspx</comments><wfw:commentRss>http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/commentrss.aspx?PostID=10572</wfw:commentRss><description>&lt;p&gt;Somehow I've made it to ComputerWeekly's blogging beauty competition - the "IT Blog Awards 08".&lt;/p&gt; &lt;p&gt;Please help this author by adding your vote if you feel that way inclined :-) Click the picture below...&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.computerweekly.com/blogawards.htm"&gt;&lt;img height="500" alt="image" src="http://mtaulty.com/blog/images/OutrageousSelfPromotion_14A5E/image.png" width="632" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://mtaulty.com/CommunityServer/aggbug.aspx?PostID=10572" width="1" height="1"&gt;</description></item><item><title>Hardware Budgets</title><link>http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2008/07/03/10568.aspx</link><pubDate>Thu, 03 Jul 2008 09:25:10 GMT</pubDate><guid isPermaLink="false">c62f47b3-9054-4265-9c0c-549d811810c2:10568</guid><dc:creator>mtaulty</dc:creator><slash:comments>0</slash:comments><comments>http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/comments/10568.aspx</comments><wfw:commentRss>http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/commentrss.aspx?PostID=10568</wfw:commentRss><description>&lt;p&gt;The first work development machine that I bought to sit on my desk cost approximately £20K. That was 16 years ago so you'd have to guess that'd be about the equivalent of £40K (or more) today. It was a huge amount of money but, at the time, it was a cost of doing business and so (rightly) no-one questioned that it had to be done if we wanted to get our product built.&lt;/p&gt; &lt;p&gt;It definitely cost more than my salary at the time and I remember that I bought the wrong monitor for it by mistake and felt pretty scared of having to tell my boss who turned out to be very understanding ( thanks :-) ).&lt;/p&gt; &lt;p&gt;Today, hardware is incredibly cheap and staggeringly powerful.&lt;/p&gt; &lt;p&gt;Yet companies (including mine) seem loathe to buy developers/technical types the latest kit? &lt;/p&gt; &lt;p&gt;Why? &lt;/p&gt; &lt;p&gt;It's cheap and it's such a quick win when it comes to making technical people feel valued.&lt;/p&gt; &lt;p&gt;It's even better if you let people &lt;em&gt;choose&lt;/em&gt; their own kit as I suspect;&lt;/p&gt; &lt;ol&gt; &lt;li&gt;They feel attached to it having selected it themselves.&lt;/li&gt; &lt;li&gt;They're more likely to want to keep it longer because of (1).&lt;/li&gt; &lt;li&gt;They're more likely to try and address any technical short-comings in it having chosen it themselves rather than calling it a "piece of junk" and ringing a helpdesk to see if they can get it replaced because they never liked it in the first place.&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;Naturally, Joel knows this (and a lot of other things) and wrote it into his guidelines to understanding developers under the category of "Toys";&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;a title="http://www.joelonsoftware.com/articles/FieldGuidetoDevelopers.html" href="http://www.joelonsoftware.com/articles/FieldGuidetoDevelopers.html"&gt;http://www.joelonsoftware.com/articles/FieldGuidetoDevelopers.html&lt;/a&gt;&amp;nbsp;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;From time to time I re-read that article as it always cheers me up - makes me wish I was working for Joel :-)&lt;/p&gt; &lt;p&gt;So...if you're thinking about how to motivate technical people here's a tip - give them a hardware budget and the discretion to spend it. Naturally, you'll need to beat them up if they go and buy the wrong things but the people who do that probably need pushing towards the door anyway ;-)&lt;/p&gt;&lt;img src="http://mtaulty.com/CommunityServer/aggbug.aspx?PostID=10568" width="1" height="1"&gt;</description><category domain="http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/category/1028.aspx">Off Topic</category></item><item><title>On Entity Framework, Concurrency</title><link>http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2008/07/02/10564.aspx</link><pubDate>Wed, 02 Jul 2008 21:22:09 GMT</pubDate><guid isPermaLink="false">c62f47b3-9054-4265-9c0c-549d811810c2:10564</guid><dc:creator>mtaulty</dc:creator><slash:comments>3</slash:comments><comments>http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/comments/10564.aspx</comments><wfw:commentRss>http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/commentrss.aspx?PostID=10564</wfw:commentRss><description>&lt;p&gt;This is similar but not at all identical to &lt;a href="http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2008/07/01/10557.aspx#comments"&gt;this post about LINQ to SQL&lt;/a&gt; because it's using a different framework and that has different capabilities.&lt;/p&gt; &lt;p&gt;Someone mailed and asked how we can detect concurrency problems with Entity Framework in order to ensure that when we submit changes to the DB we first;&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Present the user with a list of all the concurrency errors in one go  &lt;li&gt;Present the user with their changes versus the DB's current data  &lt;li&gt;Ask the user how to go about resolving each issue  &lt;li&gt;Repeat until all the changes get to the DB one way or another&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;I can use the same tables and scripts and so on that I used in the previous post about LINQ to SQL. So...if I've got this table in my DB;&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;create&lt;/span&gt; &lt;span class="kwrd"&gt;table&lt;/span&gt; Person
(
  id &lt;span class="kwrd"&gt;int&lt;/span&gt; &lt;span class="kwrd"&gt;identity&lt;/span&gt; &lt;span class="kwrd"&gt;primary&lt;/span&gt; &lt;span class="kwrd"&gt;key&lt;/span&gt;,
  firstName nvarchar(30),
  lastName nvarchar(30),
  &lt;span class="kwrd"&gt;timestamp&lt;/span&gt; 
)
&lt;/pre&gt;
&lt;p&gt;with data;&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;insert&lt;/span&gt; person(firstname,lastname) &lt;span class="kwrd"&gt;values&lt;/span&gt;(&lt;span class="str"&gt;'first1'&lt;/span&gt;, &lt;span class="str"&gt;'last1'&lt;/span&gt;)
&lt;span class="kwrd"&gt;insert&lt;/span&gt; person(firstname,lastname) &lt;span class="kwrd"&gt;values&lt;/span&gt;(&lt;span class="str"&gt;'first2'&lt;/span&gt;, &lt;span class="str"&gt;'last2'&lt;/span&gt;)
&lt;span class="kwrd"&gt;insert&lt;/span&gt; person(firstname,lastname) &lt;span class="kwrd"&gt;values&lt;/span&gt;(&lt;span class="str"&gt;'first3'&lt;/span&gt;, &lt;span class="str"&gt;'last3'&lt;/span&gt;)&lt;/pre&gt;
&lt;p&gt;and I bring this into an Entity Framework based project using the usual route and I make sure that I'm checking the &lt;strong&gt;timestamp&lt;/strong&gt; for concurrency by altering the properties on the diagram as below;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://mtaulty.com/blog/images/OnEntityFrameworkConcurrencyandTimestamp_D937/image.png"&gt;&lt;img height="358" alt="image" src="http://mtaulty.com/blog/images/OnEntityFrameworkConcurrencyandTimestamp_D937/image_thumb.png" width="644" border="0"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;and then I can start to write some code (similar to my LINQ to SQL) code as below;&lt;/p&gt;&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;using&lt;/span&gt; (demoEntities context = &lt;span class="kwrd"&gt;new&lt;/span&gt; demoEntities())
    {
      Console.WriteLine(&lt;span class="str"&gt;"Enter a new surname"&lt;/span&gt;);
      &lt;span class="kwrd"&gt;string&lt;/span&gt; surname = Console.ReadLine();

      var people = context.Person.ToList();

      &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (Person p &lt;span class="kwrd"&gt;in&lt;/span&gt; people)
      {
        p.lastName = surname;
      }
      Console.WriteLine(&lt;span class="str"&gt;"Now's the time to cause a concurrency violation"&lt;/span&gt;);
      Console.ReadLine();

      &lt;span class="kwrd"&gt;try&lt;/span&gt;
      {
        context.SaveChanges();
      }
      &lt;span class="kwrd"&gt;catch&lt;/span&gt; (OptimisticConcurrencyException ex)
      {
        &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (ObjectStateEntry item &lt;span class="kwrd"&gt;in&lt;/span&gt; ex.StateEntries)
        {
          Console.WriteLine(&lt;span class="str"&gt;"Found an item"&lt;/span&gt;);
        }
      }
    }&lt;/pre&gt;
&lt;p&gt;The "problem" that I've got here is that there's no version of &lt;strong&gt;SaveChanges&lt;/strong&gt; on the &lt;strong&gt;ObjectContext&lt;/strong&gt; that allows for you to continue when you hit a concurrency error making it hard for me to build a list of "all the concurrency problems".&lt;/p&gt;
&lt;p&gt;So, if I cause a concurrency problem at the &lt;strong&gt;Console.ReadLine()&lt;/strong&gt; above with &lt;em&gt;two&lt;/em&gt; of my entities by doing something like;&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;update&lt;/span&gt; person &lt;span class="kwrd"&gt;set&lt;/span&gt; lastName=&lt;span class="str"&gt;'anything'&lt;/span&gt; &lt;span class="kwrd"&gt;where&lt;/span&gt; id=2
&lt;span class="kwrd"&gt;update&lt;/span&gt; person &lt;span class="kwrd"&gt;set&lt;/span&gt; lastName=&lt;span class="str"&gt;'else'&lt;/span&gt; &lt;span class="kwrd"&gt;where&lt;/span&gt; id=3&lt;/pre&gt;&lt;pre class="csharpcode"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;p&gt;then what I'm going to see is 1 an exception containing the details of a single concurrency exception. I'm not going to get to "see" the second concurrency exception until I clear the first one.&lt;/p&gt;
&lt;p&gt;How can I clear the first one? By refreshing the entity's original values from the DB whilst keeping my changes.&lt;/p&gt;
&lt;p&gt;That's all fine in that I can write code like this but if I wanted to build up a complete list of all my concurrency problems and then present them to a user as a list before making any changes to the data then this code;&lt;/p&gt;&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;using&lt;/span&gt; (demoEntities context = &lt;span class="kwrd"&gt;new&lt;/span&gt; demoEntities())
    {
      Console.WriteLine(&lt;span class="str"&gt;"Enter a new surname"&lt;/span&gt;);
      &lt;span class="kwrd"&gt;string&lt;/span&gt; surname = Console.ReadLine();

      var people = context.Person.ToList();

      &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (Person p &lt;span class="kwrd"&gt;in&lt;/span&gt; people)
      {
        p.lastName = surname;
      }
      Console.WriteLine(&lt;span class="str"&gt;"Now's the time to cause a concurrency violation"&lt;/span&gt;);
      Console.ReadLine();

      &lt;span class="kwrd"&gt;bool&lt;/span&gt; allSaved = &lt;span class="kwrd"&gt;false&lt;/span&gt;;
      List&amp;lt;&lt;span class="kwrd"&gt;object&lt;/span&gt;&amp;gt; failedEntities = &lt;span class="kwrd"&gt;new&lt;/span&gt; List&amp;lt;&lt;span class="kwrd"&gt;object&lt;/span&gt;&amp;gt;();

      &lt;span class="kwrd"&gt;while&lt;/span&gt; (!allSaved)
      {
        &lt;span class="kwrd"&gt;try&lt;/span&gt;
        {
          context.SaveChanges();
          allSaved = &lt;span class="kwrd"&gt;true&lt;/span&gt;;
        }
        &lt;span class="kwrd"&gt;catch&lt;/span&gt; (OptimisticConcurrencyException ex)
        {
          &lt;span class="rem"&gt;// This will only iterate once.&lt;/span&gt;
          &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (ObjectStateEntry item &lt;span class="kwrd"&gt;in&lt;/span&gt; ex.StateEntries)
          {
            context.Refresh(RefreshMode.ClientWins, item.Entity);
            failedEntities.Add(item.Entity);
          }
        }
      }
      &lt;span class="rem"&gt;// Spot the problem? It's too late already...&lt;/span&gt;
      Console.WriteLine(&lt;span class="str"&gt;"Encountered {0} concurrency problems along the way"&lt;/span&gt;,
        failedEntities.Count);
    }&lt;/pre&gt;
&lt;p&gt;has an obvious problem in that by the time my code has figured out the list of entities that have concurrency problems it's all too late because I've already submitted the changes to the DB without having had any opportunity to consult the user (i.e. the last call to &lt;strong&gt;SaveChanges&lt;/strong&gt; will actually &lt;em&gt;work&lt;/em&gt;).&lt;/p&gt;
&lt;p&gt;The only way that I can think of stopping that happening is to ensure that the transaction will roll back in the case where &lt;strong&gt;SaveChanges&lt;/strong&gt; fails ( this would happen anyway ) and the case where it succeeds ( this would not happen usually ).&lt;/p&gt;
&lt;p&gt;Something along the lines of;&lt;/p&gt;&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;using&lt;/span&gt; (demoEntities context = &lt;span class="kwrd"&gt;new&lt;/span&gt; demoEntities())
    {
      Console.WriteLine(&lt;span class="str"&gt;"Enter a new surname"&lt;/span&gt;);
      &lt;span class="kwrd"&gt;string&lt;/span&gt; surname = Console.ReadLine();

      var people = context.Person.ToList();

      &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (Person p &lt;span class="kwrd"&gt;in&lt;/span&gt; people)
      {
        p.lastName = surname;
      }
      Console.WriteLine(&lt;span class="str"&gt;"Now's the time to cause a concurrency violation"&lt;/span&gt;);
      Console.ReadLine();

      &lt;span class="kwrd"&gt;bool&lt;/span&gt; allSaved = &lt;span class="kwrd"&gt;false&lt;/span&gt;;

      &lt;span class="kwrd"&gt;while&lt;/span&gt; (!allSaved)
      {
        &lt;span class="kwrd"&gt;bool&lt;/span&gt; allTried = &lt;span class="kwrd"&gt;false&lt;/span&gt;;
        List&amp;lt;&lt;span class="kwrd"&gt;object&lt;/span&gt;&amp;gt; failedEntities = &lt;span class="kwrd"&gt;new&lt;/span&gt; List&amp;lt;&lt;span class="kwrd"&gt;object&lt;/span&gt;&amp;gt;();

        &lt;span class="kwrd"&gt;while&lt;/span&gt; (!allTried)
        {
          TransactionScope scope = &lt;span class="kwrd"&gt;new&lt;/span&gt; TransactionScope();

          &lt;span class="kwrd"&gt;try&lt;/span&gt;
          {
            context.SaveChanges(&lt;span class="kwrd"&gt;false&lt;/span&gt;);

            allTried = &lt;span class="kwrd"&gt;true&lt;/span&gt;;

            &lt;span class="kwrd"&gt;if&lt;/span&gt; (failedEntities.Count == 0)
            {
              scope.Complete();
            }
            scope.Dispose();
          }
          &lt;span class="kwrd"&gt;catch&lt;/span&gt; (OptimisticConcurrencyException ex)
          {
            scope.Dispose();

            &lt;span class="rem"&gt;// This will only iterate once.&lt;/span&gt;
            &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (ObjectStateEntry item &lt;span class="kwrd"&gt;in&lt;/span&gt; ex.StateEntries)
            {
              context.Refresh(RefreshMode.ClientWins, item.Entity);
              failedEntities.Add(item.Entity);
            }
          }
        }
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (!(allSaved = failedEntities.Count == 0))
        {
          Console.WriteLine(&lt;span class="str"&gt;"Hit {0} concurrency problems"&lt;/span&gt;, failedEntities.Count);

          &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (&lt;span class="kwrd"&gt;object&lt;/span&gt; entity &lt;span class="kwrd"&gt;in&lt;/span&gt; failedEntities)
          {
            ObjectStateEntry stateEntry =
              context.ObjectStateManager.GetObjectStateEntry(entity);

            RefreshMode mode = PromptUserForEntityConflict(stateEntry);

            context.Refresh(mode, entity);
          }
        }
      }
      &lt;span class="rem"&gt;// Finally, we can make current == original.&lt;/span&gt;
      context.AcceptAllChanges();
    }
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;with a couple of little functions;&lt;/p&gt;&lt;pre class="csharpcode"&gt;  &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; RefreshMode PromptUserForEntityConflict(ObjectStateEntry entry)
  {
    RefreshMode mode = RefreshMode.StoreWins;

    Console.WriteLine(&lt;span class="str"&gt;"Conflict on entity with key [{0}]"&lt;/span&gt;,
      EntityKeyToString(entry));

    &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (&lt;span class="kwrd"&gt;string&lt;/span&gt; propertyName &lt;span class="kwrd"&gt;in&lt;/span&gt; entry.GetModifiedProperties())
    {
      Console.WriteLine(&lt;span class="str"&gt;"\tProperty [{0}], your value [{1}], db value [{2}]"&lt;/span&gt;,
        propertyName, entry.CurrentValues[propertyName],
        entry.OriginalValues[propertyName]);
    }

    Console.WriteLine(&lt;span class="str"&gt;"Do you want to keep your values [y] or db values [d]?"&lt;/span&gt;);

    mode = Console.ReadLine() == &lt;span class="str"&gt;"y"&lt;/span&gt; ?
      RefreshMode.ClientWins : RefreshMode.StoreWins;

    &lt;span class="kwrd"&gt;return&lt;/span&gt; (mode);
  }
  &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; EntityKeyToString(ObjectStateEntry entry)
  {
    StringBuilder sb = &lt;span class="kwrd"&gt;new&lt;/span&gt; StringBuilder();

    &lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;int&lt;/span&gt; i = 0; i &amp;lt; entry.EntityKey.EntityKeyValues.Length; i++)
    {
      sb.AppendFormat(&lt;span class="str"&gt;"{0}{1}"&lt;/span&gt;, i &amp;gt; 0 ? &lt;span class="str"&gt;","&lt;/span&gt; : &lt;span class="kwrd"&gt;string&lt;/span&gt;.Empty,
        entry.EntityKey.EntityKeyValues[i]);
    }
    &lt;span class="kwrd"&gt;return&lt;/span&gt; (sb.ToString());
  }&lt;/pre&gt;
&lt;p&gt;This seems to be about the best I can do &lt;strong&gt;if&lt;/strong&gt; I need to present the user with &lt;em&gt;all&lt;/em&gt; (current) concurrency problems in a single go and also present them with their values versus the database values.&lt;/p&gt;
&lt;p&gt;In a lot of systems, concurrency issues are rare (e.g. generally I'm hoping that when I'm updating my bank account details via a call centre there isn't someone else also updating my details :-)) so this might not be such a common scenario but, with this implementation it means that if you have M modifications to update which cause N concurrency exceptions then you'll need at least N+2 trips to the database (with quite a lot of rolled back transactions) to make this work.&lt;/p&gt;
&lt;p&gt;Feel free to suggest improvements and I'll add them here.&lt;/p&gt;&lt;img src="http://mtaulty.com/CommunityServer/aggbug.aspx?PostID=10564" width="1" height="1"&gt;</description><category domain="http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/category/1000.aspx">.NET</category><category domain="http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/category/1005.aspx">ADO.NET</category><category domain="http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/category/1024.aspx">Entity Framework</category><category domain="http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/category/1026.aspx">Data Access</category></item><item><title>Silverlight &amp;amp; Virtual Earth</title><link>http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2008/07/02/10563.aspx</link><pubDate>Wed, 02 Jul 2008 20:25:47 GMT</pubDate><guid isPermaLink="false">c62f47b3-9054-4265-9c0c-549d811810c2:10563</guid><dc:creator>mtaulty</dc:creator><slash:comments>0</slash:comments><comments>http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/comments/10563.aspx</comments><wfw:commentRss>http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/commentrss.aspx?PostID=10563</wfw:commentRss><description>&lt;p&gt;Fantastic demonstration from IDV solutions;&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;a title="http://silverlight.idvsolutions.com/" href="http://silverlight.idvsolutions.com/"&gt;http://silverlight.idvsolutions.com/&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;It'd be really cool to be able to copy a link once you've annotated a map and share it with someone else.&lt;/p&gt; &lt;p&gt;I liked the flyout menus on the tools on the right hand side :-)&lt;/p&gt;&lt;img src="http://mtaulty.com/CommunityServer/aggbug.aspx?PostID=10563" width="1" height="1"&gt;</description><category domain="http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/category/1015.aspx">Silverlight</category><category domain="http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/category/1021.aspx">Windows Live</category></item><item><title>Give me back my CPU(s)</title><link>http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2008/07/02/10558.aspx</link><pubDate>Wed, 02 Jul 2008 08:29:02 GMT</pubDate><guid isPermaLink="false">c62f47b3-9054-4265-9c0c-549d811810c2:10558</guid><dc:creator>mtaulty</dc:creator><slash:comments>1</slash:comments><comments>http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/comments/10558.aspx</comments><wfw:commentRss>http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/commentrss.aspx?PostID=10558</wfw:commentRss><description>&lt;p&gt;Too many times I'm seeing this in my system tray;&lt;/p&gt; &lt;p&gt;&lt;a href="http://mtaulty.com/blog/images/GivemebackmyCPUs_8551/image.png"&gt;&lt;img height="40" alt="image" src="http://mtaulty.com/blog/images/GivemebackmyCPUs_8551/image_thumb.png" width="41" border="0"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;What is that? It's Process Explorer ( I run that instead of Task Manager ) saying that my CPU is pegged ( again ).&lt;/p&gt; &lt;p&gt;The primary culprits are;&lt;/p&gt; &lt;ol&gt; &lt;li&gt;My Anti-Virus software. This has never detected a virus for me yet and so, generally, I run the risk and I stop the service and get my CPU back.&lt;/li&gt; &lt;li&gt;The search indexer ( on Vista ). Generally, I fix this by restarting the service.&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;I wonder how many users throw up their arms and think that either;&lt;/p&gt; &lt;ol&gt; &lt;li&gt;The OS is broken.&lt;/li&gt; &lt;li&gt;The PC is broken.&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;I hope that future versions of Windows do something about run-away processes. It's a tricky problem to solve but when I wrote &lt;a href="http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2006/03/09/5785.aspx"&gt;here&lt;/a&gt; about what I was hoping for Vista, this was one of my top "hopes" and I don't think that we've really got there just yet.&lt;/p&gt;&lt;img src="http://mtaulty.com/CommunityServer/aggbug.aspx?PostID=10558" width="1" height="1"&gt;</description><category domain="http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/category/1020.aspx">Windows Vista</category></item><item><title>On LINQ to SQL, Concurrency and Timestamps</title><link>http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2008/07/01/10557.aspx</link><pubDate>Tue, 01 Jul 2008 22:10:31 GMT</pubDate><guid isPermaLink="false">c62f47b3-9054-4265-9c0c-549d811810c2:10557</guid><dc:creator>mtaulty</dc:creator><slash:comments>3</slash:comments><comments>http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/comments/10557.aspx</comments><wfw:commentRss>http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/commentrss.aspx?PostID=10557</wfw:commentRss><description>&lt;p&gt;I came across a bit of a glitch in using timestamps for checking concurrency violations in LINQ to SQL and thought I'd share.&lt;/p&gt; &lt;p&gt;Say I've got a table like;&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;create&lt;/span&gt; &lt;span class="kwrd"&gt;table&lt;/span&gt; Person
(
  id &lt;span class="kwrd"&gt;int&lt;/span&gt; &lt;span class="kwrd"&gt;identity&lt;/span&gt; &lt;span class="kwrd"&gt;primary&lt;/span&gt; &lt;span class="kwrd"&gt;key&lt;/span&gt;,
  firstName nvarchar(30),
  lastName nvarchar(30),
  &lt;span class="kwrd"&gt;timestamp&lt;/span&gt; 
)&lt;/pre&gt;
&lt;p&gt;so, we have a simple table that has a timestamp on it and I want to use that to detect any concurrency problems that I might have in LINQ to SQL.&lt;/p&gt;
&lt;p&gt;Let's populate this table with some data;&lt;/p&gt;&lt;pre class="csharpcode"&gt;insert person(firstname,lastname) values(&lt;span class="str"&gt;'first1'&lt;/span&gt;, &lt;span class="str"&gt;'last1'&lt;/span&gt;)
insert person(firstname,lastname) values(&lt;span class="str"&gt;'first2'&lt;/span&gt;, &lt;span class="str"&gt;'last2'&lt;/span&gt;)
insert person(firstname,lastname) values(&lt;span class="str"&gt;'first3'&lt;/span&gt;, &lt;span class="str"&gt;'last3'&lt;/span&gt;)&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;and then I can bring that into my LINQ to SQL environment and I can check what the concurrency options are set to;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://mtaulty.com/blog/images/OnLINQtoSQLConcurrencyandTimestamps_1319A/image.png"&gt;&lt;img height="361" alt="image" src="http://mtaulty.com/blog/images/OnLINQtoSQLConcurrencyandTimestamps_1319A/image_thumb.png" width="644" border="0"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;So, you can see that we've got &lt;strong&gt;Update Check&lt;/strong&gt; set to &lt;strong&gt;Always&lt;/strong&gt; and that means that the timestamp will be added to any where clauses for Deletes or Updates and if a particular update doesn't find any row to update because of that where clause then we have a concurrency violation.&lt;/p&gt;
&lt;p&gt;Note also that &lt;strong&gt;Auto-Sync&lt;/strong&gt; is set to &lt;strong&gt;Always&lt;/strong&gt; which is a good thing because it means that if we insert an entity we'll automatically get the timestamp back and if we update an entity we'll similarly get an updated timestamp so that the timestamp in the &lt;strong&gt;&lt;em&gt;original values&lt;/em&gt;&lt;/strong&gt; of our entity in memory will represent the timestamp of the record when we queried/inserted/updated it and will only get "stale" if someone else were to update it (or delete it) in the meantime.&lt;/p&gt;
&lt;p&gt;So, with LINQ to SQL we can write some code such as the stuff below which prompts for a new surname, changes the value in the entities that it has queried then tries to do a &lt;strong&gt;SubmitChanges&lt;/strong&gt; and tries to make sure that it captures as many concurrency violations as it can ( the &lt;strong&gt;ContinueOnConflict&lt;/strong&gt; parameter ).&lt;/p&gt;&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;using&lt;/span&gt; (DemoDataContext ctx = &lt;span class="kwrd"&gt;new&lt;/span&gt; DemoDataContext())
    {
      var people = ctx.Persons.ToList();

      Console.WriteLine(&lt;span class="str"&gt;"Enter a new surname"&lt;/span&gt;);
      &lt;span class="kwrd"&gt;string&lt;/span&gt; surname = Console.ReadLine();

      &lt;span class="rem"&gt;// Cause some changes.&lt;/span&gt;
      &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (Person p &lt;span class="kwrd"&gt;in&lt;/span&gt; people)
      {
        p.lastName = surname;
      }
      &lt;span class="rem"&gt;// HERE...&lt;/span&gt;
      Console.WriteLine(&lt;span class="str"&gt;"Now's the time to cause a concurrency violation"&lt;/span&gt;);
      Console.ReadLine();

      &lt;span class="kwrd"&gt;bool&lt;/span&gt; allSaved = &lt;span class="kwrd"&gt;false&lt;/span&gt;;

      &lt;span class="kwrd"&gt;while&lt;/span&gt; (!allSaved)
      {
        &lt;span class="kwrd"&gt;try&lt;/span&gt;
        {
          ctx.SubmitChanges(ConflictMode.ContinueOnConflict);
          allSaved = &lt;span class="kwrd"&gt;true&lt;/span&gt;;
        }
        &lt;span class="kwrd"&gt;catch&lt;/span&gt; (ChangeConflictException ex)
        {
          Console.WriteLine(&lt;span class="str"&gt;"Hit a conflict - fixing it!"&lt;/span&gt;);

          &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (ObjectChangeConflict conflict &lt;span class="kwrd"&gt;in&lt;/span&gt; ctx.ChangeConflicts)
          {
            conflict.Resolve(RefreshMode.KeepChanges);
          }
        }
        &lt;span class="kwrd"&gt;catch&lt;/span&gt; (Exception ex)
        {
          Console.WriteLine(&lt;span class="str"&gt;"Hit an unexpected exception [{0}]"&lt;/span&gt;,
            ex.Message);
        }
      }
    }&lt;/pre&gt;
&lt;p&gt;When we hit the line of code marked &lt;strong&gt;HERE&lt;/strong&gt; above, I go and run this piece of T-SQL;&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;update&lt;/span&gt; person &lt;span class="kwrd"&gt;set&lt;/span&gt; lastName=&lt;span class="str"&gt;'anything'&lt;/span&gt; &lt;span class="kwrd"&gt;where&lt;/span&gt; id=2
&lt;span class="kwrd"&gt;update&lt;/span&gt; person &lt;span class="kwrd"&gt;set&lt;/span&gt; lastName=&lt;span class="str"&gt;'else'&lt;/span&gt; &lt;span class="kwrd"&gt;where&lt;/span&gt; id=3&lt;/pre&gt;
&lt;p&gt;to cause concurrency problems for row number 2 and number 3 in my database.&lt;/p&gt;
&lt;p&gt;What &lt;em&gt;should&lt;/em&gt; happen;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;We read 3 entities with timestamps T1, T2, T3. 
&lt;li&gt;We modify the surnames in our code. 
&lt;li&gt;We use T-SQL to modify the timestamps T2, T3 in the database to ( say ) TM2 and TM3. 
&lt;li&gt;We submit our changes. 
&lt;li&gt;Our modifications for entities 2 and 3 will fail because T2!=TM2 and T3!=TM3. Our transaction is rolled back. 
&lt;li&gt;We use &lt;strong&gt;Resolve&lt;/strong&gt; in order to keep any changes that we have made in our code ( i.e. the surname modification ) but to refresh the other entity values from the DB. 
&lt;li&gt;We now have in our program entities with timestamps T1, TM2, TM3 
&lt;li&gt;We submit our changes. 
&lt;li&gt;The code completes.&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;However, that's not what happens when the code does. What happens is that we hit an unexpected exception at &lt;strong&gt;8&lt;/strong&gt; above and my &lt;strong&gt;Console.WriteLine&lt;/strong&gt; writes it out;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Hit an unexpected exception [Value of member 'timestamp' of an object of type 'Person' changed.&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;What's going on here? I &lt;em&gt;think&lt;/em&gt; what's happening here is that when we hit the call to &lt;strong&gt;SubmitChanges&lt;/strong&gt; we go to the database to update 3 entities. The first update works so we update the timestamp. The 2nd update fails and so does the 3rd so we rollback the transaction. 
&lt;p&gt;&lt;strong&gt;However, we've updated the timestamp on that 1st entity&lt;/strong&gt;. 
&lt;p&gt;We then go and resolve the 2 concurrency violations we've got before calling &lt;strong&gt;SubmitChanges&lt;/strong&gt; again. It takes a look at that first entity which didn't have a concurrency problem but &lt;em&gt;does &lt;/em&gt;now have a modified timestamp and still needs updating in the database ( because the transaction was rolled back ) and says &lt;strong&gt;"Hey, you're not meant to change generated columns like this!!".&lt;/strong&gt; 
&lt;p&gt;Got it? 
&lt;h5&gt;Option - Stop LINQ to SQL from Updating the TimeStamp Automatically on Update&lt;/h5&gt;
&lt;p&gt;The timestamp is only being updated because we have allowed the &lt;strong&gt;Auto-Sync&lt;/strong&gt; property to be default to &lt;strong&gt;Always&lt;/strong&gt; in the mapping information. That means "re-sync this column whenever we insert, update".&lt;/p&gt;
&lt;p&gt;We could change this so that we only do &lt;strong&gt;Auto-Sync&lt;/strong&gt; on &lt;strong&gt;Insert&lt;/strong&gt; by setting;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://mtaulty.com/blog/images/OnLINQtoSQLConcurrencyandTimestamps_1319A/image_3.png"&gt;&lt;img height="375" alt="image" src="http://mtaulty.com/blog/images/OnLINQtoSQLConcurrencyandTimestamps_1319A/image_thumb_3.png" width="644" border="0"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Now, our code as it originally stands is going to work just fine if I re-run it under the same conditions where I cause a concurrency violation at the line marked &lt;strong&gt;HERE &lt;/strong&gt;because when we hit the initial call to &lt;strong&gt;SubmitChanges&lt;/strong&gt; which throws a &lt;strong&gt;ChangeConflictException&lt;/strong&gt; we catch that exception, call &lt;strong&gt;Resolve&lt;/strong&gt; on the 2 rows with the problems and then we call &lt;strong&gt;SubmitChanges&lt;/strong&gt; again and we've never updated the timestamp on row number 1.&lt;/p&gt;
&lt;p&gt;However...this isn't a free ride.&lt;/p&gt;
&lt;p&gt;The problem with switching &lt;strong&gt;Auto-Sync&lt;/strong&gt; to &lt;strong&gt;OnInsert&lt;/strong&gt; means that whenever we actually do a successful update we &lt;em&gt;won't&lt;/em&gt; update the timestamp to reflect the latest value that we just generated in the database.&lt;/p&gt;
&lt;p&gt;So, whenever we call &lt;strong&gt;SubmitChanges&lt;/strong&gt; for subsequent updates we will see superfluous concurrency exceptions for every row that &lt;em&gt;didn't&lt;/em&gt; hit a concurrency exception the last time we called &lt;strong&gt;SubmitChanges.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;That is, this code (which runs forever) will &lt;em&gt;work&lt;/em&gt;;&lt;/p&gt;&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;using&lt;/span&gt; (DemoDataContext ctx = &lt;span class="kwrd"&gt;new&lt;/span&gt; DemoDataContext())
    {
      var people = ctx.Persons.ToList();

      &lt;span class="kwrd"&gt;while&lt;/span&gt; (&lt;span class="kwrd"&gt;true&lt;/span&gt;)
      {
        Console.WriteLine(&lt;span class="str"&gt;"Enter a new surname"&lt;/span&gt;);
        &lt;span class="kwrd"&gt;string&lt;/span&gt; surname = Console.ReadLine();

        &lt;span class="rem"&gt;// Cause some changes.&lt;/span&gt;
        &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (Person p &lt;span class="kwrd"&gt;in&lt;/span&gt; people)
        {
          p.lastName = surname;
        }
        &lt;span class="rem"&gt;// HERE...&lt;/span&gt;
        Console.WriteLine(&lt;span class="str"&gt;"Now's the time to cause a concurrency violation"&lt;/span&gt;);
        Console.ReadLine();

        &lt;span class="kwrd"&gt;bool&lt;/span&gt; allSaved = &lt;span class="kwrd"&gt;false&lt;/span&gt;;

        &lt;span class="kwrd"&gt;while&lt;/span&gt; (!allSaved)
        {
          &lt;span class="kwrd"&gt;try&lt;/span&gt;
          {
            ctx.SubmitChanges(ConflictMode.ContinueOnConflict);
            Console.WriteLine(&lt;span class="str"&gt;"Submitted changes"&lt;/span&gt;);
            allSaved = &lt;span class="kwrd"&gt;true&lt;/span&gt;;
          }
          &lt;span class="kwrd"&gt;catch&lt;/span&gt; (ChangeConflictException ex)
          {
            Console.WriteLine(&lt;span class="str"&gt;"Hit a conflict - fixing it!"&lt;/span&gt;);

            &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (ObjectChangeConflict conflict &lt;span class="kwrd"&gt;in&lt;/span&gt; ctx.ChangeConflicts)
            {
              conflict.Resolve(RefreshMode.KeepChanges);
            }
          }
          &lt;span class="kwrd"&gt;catch&lt;/span&gt; (Exception ex)
          {
            Console.WriteLine(&lt;span class="str"&gt;"Hit an unexpected exception [{0}]"&lt;/span&gt;,
              ex.Message);
          }
        }
      }
    }
&lt;/pre&gt;
&lt;p&gt;and it'll work regardless of whether I cause concurrency problems at the line marked &lt;strong&gt;HERE. &lt;/strong&gt;However, once the loop has executed once we run the risk of hitting "false" concurrency problems at the call to &lt;strong&gt;SubmitChanges&lt;/strong&gt; for any rows that have out of date timestamps because we did not update them the last time we did an update.&lt;/p&gt;
&lt;p&gt;The other thing that comes to mind here is that this all depends on the &lt;strong&gt;&lt;a href="http://blogs.msdn.com/dinesh.kulkarni/archive/2008/04/27/lifetime-of-a-linq-to-sql-datacontext.aspx"&gt;lifetime of your DataContext&lt;/a&gt;. &lt;/strong&gt;If you just use it for one "unit of work" then this isn't really going to bite you in the same way because &lt;strong&gt;Auto-Sync&lt;/strong&gt; doesn't seem so relevant if you're going to throw your &lt;strong&gt;DataContext&lt;/strong&gt; away after you call &lt;strong&gt;SubmitChanges&lt;/strong&gt; anyway.&lt;/p&gt;
&lt;p&gt;And the last thing is that this won't affect you at all unless you're using generated columns like timestamps for concurrency checking.&lt;/p&gt;&lt;img src="http://mtaulty.com/CommunityServer/aggbug.aspx?PostID=10557" width="1" height="1"&gt;</description><category domain="http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/category/1000.aspx">.NET</category><category domain="http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/category/1001.aspx">LINQ</category><category domain="http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/category/1005.aspx">ADO.NET</category><category domain="http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/category/1016.aspx">SQL Server</category><category domain="http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/category/1026.aspx">Data Access</category></item><item><title>Silverlight and ADO.NET Data Services ( 2 )</title><link>http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2008/06/30/10549.aspx</link><pubDate>Mon, 30 Jun 2008 22:38:51 GMT</pubDate><guid isPermaLink="false">c62f47b3-9054-4265-9c0c-549d811810c2:10549</guid><dc:creator>mtaulty</dc:creator><slash:comments>2</slash:comments><comments>http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/comments/10549.aspx</comments><wfw:commentRss>http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/commentrss.aspx?PostID=10549</wfw:commentRss><description>&lt;p&gt;Following on from &lt;a href="http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2008/06/30/10548.aspx"&gt;this last post&lt;/a&gt;, if I start to edit the data in the grid and change some value then the property value will change in the underlying class but nothing else will happen. That is, the &lt;strong&gt;NorthwindEntities&lt;/strong&gt; class which is managing my data for me client-side ( which is derived from &lt;strong&gt;DataServiceContext&lt;/strong&gt; ) isn't going to be aware of those modifications.&lt;/p&gt; &lt;p&gt;Why not? If we have a look at a property on a generated class such as this one for the &lt;strong&gt;CompanyName&lt;/strong&gt; on the &lt;strong&gt;Customers&lt;/strong&gt; class;&lt;/p&gt;&lt;pre class="csharpcode"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; CompanyName
        {
            get
            {
                &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;this&lt;/span&gt;._CompanyName;
            }
            set
            {
                &lt;span class="kwrd"&gt;this&lt;/span&gt;.OnCompanyNameChanging(&lt;span class="kwrd"&gt;value&lt;/span&gt;);
                &lt;span class="kwrd"&gt;this&lt;/span&gt;._CompanyName = &lt;span class="kwrd"&gt;value&lt;/span&gt;;
                &lt;span class="kwrd"&gt;this&lt;/span&gt;.OnCompanyNameChanged();
            }
        }&lt;/pre&gt;
&lt;p&gt;Now, &lt;strong&gt;OnCompanyNameChanging &lt;/strong&gt;and &lt;strong&gt;OnCompanyNameChanged&lt;/strong&gt; are partial methods with no implementation by default so nothing's going to happen when something like the &lt;strong&gt;DataGrid&lt;/strong&gt; changes a value such as &lt;strong&gt;CompanyName.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Similarly, the generated entity classes such as &lt;strong&gt;Customers&lt;/strong&gt; do not implement &lt;strong&gt;INotifyPropertyChanged&lt;/strong&gt; which means that changes in the data will not be reflected in the UI anywhere as the UI doesn't have the necessary events to sync up to. This would also be true of an ADO.NET Data Services client generated for the full .NET framework ( such as WPF ) right now as it's the same tool that's in use.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;( It wouldn't be true if you were using generated code from the Entity Framework directly in your UI ( i.e. a 2-tier solution ) because the Entity Framework &lt;strong&gt;ObjectContext&lt;/strong&gt; and generated entity classes do set up a relationship where one "tracks" the other via the &lt;strong&gt;ObjectContext's&lt;/strong&gt; &lt;strong&gt;ObjectStateManager&lt;/strong&gt; and the &lt;strong&gt;IEntityWithChangeTracker&lt;/strong&gt; interface and &lt;strong&gt;EntityObject's&lt;/strong&gt; implementation of it ).&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;So, we're not going to get automatic, 2-way databinding on these entity classes just yet ( I'm hoping that RTM might do that but I've no inside knowledge on that ) and there's not really any way that you want to try and manually add it if you've got a lot of generated classes with a lot of generated properties - way too much manual work there and ( AFAIK ) &lt;strong&gt;datasvcutil.exe &lt;/strong&gt;isn't extensible.&lt;/p&gt;
&lt;p&gt;So you might want to look at something like &lt;a href="http://www.thejoyofcode.com/Making_webdatagen_data_binding_friendly.aspx"&gt;Josh's script over here which does a crafty search-and-replace for you&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Regardless, if I edit data in my &lt;strong&gt;DataGrid&lt;/strong&gt; as I've got it currently then the edits will make it through to the underlying property on the data bound object. So, if I change my UI to add a "Save" button;&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;UserControl&lt;/span&gt;
  &lt;span class="attr"&gt;x:Class&lt;/span&gt;&lt;span class="kwrd"&gt;="BlogPostSL.Page"&lt;/span&gt;
  &lt;span class="attr"&gt;xmlns&lt;/span&gt;&lt;span class="kwrd"&gt;="http://schemas.microsoft.com/winfx/2006/xaml/presentation"&lt;/span&gt;
  &lt;span class="attr"&gt;xmlns:x&lt;/span&gt;&lt;span class="kwrd"&gt;="http://schemas.microsoft.com/winfx/2006/xaml"&lt;/span&gt;
  &lt;span class="attr"&gt;xmlns:data&lt;/span&gt;&lt;span class="kwrd"&gt;="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Grid&lt;/span&gt; &lt;span class="attr"&gt;x:Name&lt;/span&gt;&lt;span class="kwrd"&gt;="LayoutRoot"&lt;/span&gt; &lt;span class="attr"&gt;Background&lt;/span&gt;&lt;span class="kwrd"&gt;="White"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Grid.RowDefinitions&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;RowDefinition&lt;/span&gt;
        &lt;span class="attr"&gt;Height&lt;/span&gt;&lt;span class="kwrd"&gt;="8*"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;RowDefinition&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;RowDefinition&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;RowDefinition&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Grid.RowDefinitions&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;data:DataGrid&lt;/span&gt;
      &lt;span class="attr"&gt;x:Name&lt;/span&gt;&lt;span class="kwrd"&gt;="dataGrid"&lt;/span&gt;
      &lt;span class="attr"&gt;Margin&lt;/span&gt;&lt;span class="kwrd"&gt;="10"&lt;/span&gt;
      &lt;span class="attr"&gt;AutoGenerateColumns&lt;/span&gt;&lt;span class="kwrd"&gt;="True"&lt;/span&gt;
      &lt;span class="attr"&gt;ItemsSource&lt;/span&gt;&lt;span class="kwrd"&gt;="{Binding}"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Button&lt;/span&gt;
      &lt;span class="attr"&gt;Margin&lt;/span&gt;&lt;span class="kwrd"&gt;="10"&lt;/span&gt;
      &lt;span class="attr"&gt;Content&lt;/span&gt;&lt;span class="kwrd"&gt;="Get Data"&lt;/span&gt;
      &lt;span class="attr"&gt;Grid&lt;/span&gt;.&lt;span class="attr"&gt;Row&lt;/span&gt;&lt;span class="kwrd"&gt;="1"&lt;/span&gt;
      &lt;span class="attr"&gt;Click&lt;/span&gt;&lt;span class="kwrd"&gt;="OnGetData"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Button&lt;/span&gt;
      &lt;span class="attr"&gt;Margin&lt;/span&gt;&lt;span class="kwrd"&gt;="10"&lt;/span&gt;
      &lt;span class="attr"&gt;Content&lt;/span&gt;&lt;span class="kwrd"&gt;="Save Data"&lt;/span&gt;
      &lt;span class="attr"&gt;Grid&lt;/span&gt;.&lt;span class="attr"&gt;Row&lt;/span&gt;&lt;span class="kwrd"&gt;="2"&lt;/span&gt;
      &lt;span class="attr"&gt;Click&lt;/span&gt;&lt;span class="kwrd"&gt;="OnSaveData"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Grid&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;UserControl&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;and then add a little code to my code-behind class ( I've not included the whole class here, just the new method );&lt;/p&gt;&lt;pre class="csharpcode"&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; OnSaveData(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, EventArgs args)
    {
      proxy.BeginSaveChanges((asyncResult) =&amp;gt;
        {
          &lt;span class="kwrd"&gt;try&lt;/span&gt;
          {
            proxy.EndSaveChanges(asyncResult);
          }
          &lt;span class="kwrd"&gt;catch&lt;/span&gt; (Exception ex)
          {
            &lt;span class="rem"&gt;// TODO&lt;/span&gt;
            Debugger.Break();
          }
        }, &lt;span class="kwrd"&gt;null&lt;/span&gt;);
    }&lt;/pre&gt;
&lt;p&gt;Then nothing happens when that code inside my &lt;strong&gt;OnSaveData&lt;/strong&gt; function runs. If I peer inside the &lt;strong&gt;proxy&lt;/strong&gt; instance a little bit with the debugger then I can see a bunch of my &lt;strong&gt;Customers&lt;/strong&gt; entities on a list of &lt;strong&gt;EntityDescriptor&lt;/strong&gt; with a status of &lt;strong&gt;Unchanged.&lt;/strong&gt; So, we need to make sure that our grid is setting the right instance to be updated when it has been updated as in;&lt;/p&gt;&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; Page()
    {
      InitializeComponent();

      &lt;span class="kwrd"&gt;this&lt;/span&gt;.Loaded += OnLoaded;

      dataGrid.AutoGeneratingColumn += OnGeneratedColumn;
      dataGrid.CommittingEdit += OnCommittingEdit;
    }
    &lt;span class="kwrd"&gt;void&lt;/span&gt; OnCommittingEdit(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, DataGridEndingEditEventArgs e)
    {
      proxy.UpdateObject(e.Row.DataContext);
    }&lt;/pre&gt;
&lt;p&gt;Then, when I update data and click my Save button then I get my data saved back into the database. Naturally, this is being done (AFAIK!) in line with the &lt;a href="http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2008/05/30/10459.aspx"&gt;concurrency options&lt;/a&gt; and if I wanted to I could look to do &lt;a href="http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2008/05/29/10455.aspx"&gt;batch updates&lt;/a&gt; rather than individual &lt;strong&gt;PUTs&lt;/strong&gt; to make it happen as in;&lt;/p&gt;&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;void&lt;/span&gt; OnSaveData(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, EventArgs args)
    {
      proxy.BeginSaveChanges(SaveChangesOptions.Batch, (asyncResult) =&amp;gt;
        {
          &lt;span class="kwrd"&gt;try&lt;/span&gt;
          {
            proxy.EndSaveChanges(asyncResult);
          }
          &lt;span class="kwrd"&gt;catch&lt;/span&gt; (Exception ex)
          {
            &lt;span class="rem"&gt;// TODO&lt;/span&gt;
            Debugger.Break();
          }
        }, &lt;span class="kwrd"&gt;null&lt;/span&gt;);
    }&lt;/pre&gt;
&lt;p&gt;I can leave that in place and handle deletes by, for instance, trapping the delete keypress on a grid row and then making a call to &lt;strong&gt;DeleteObject.&lt;/strong&gt; I might do that by the following ( again, only listed the added code not the whole code for my &lt;strong&gt;Page&lt;/strong&gt; class );&lt;/p&gt;&lt;pre class="csharpcode"&gt;  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;partial&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Page : UserControl
  {
    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; inEdit;

    &lt;span class="kwrd"&gt;public&lt;/span&gt; Page()
    {
      InitializeComponent();

      &lt;span class="kwrd"&gt;this&lt;/span&gt;.Loaded += OnLoaded;

      dataGrid.AutoGeneratingColumn += OnGeneratedColumn;
      dataGrid.BeginningEdit += OnBeginningEdit;
      dataGrid.CommittingEdit += OnCommittingEdit;
      dataGrid.CancelingEdit += OnCancellingEdit;
      dataGrid.KeyDown += OnGridKeyDown;
    }
    &lt;span class="kwrd"&gt;void&lt;/span&gt; OnCancellingEdit(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, DataGridEndingEditEventArgs e)
    {
      inEdit = &lt;span class="kwrd"&gt;false&lt;/span&gt;;
    }
    &lt;span class="kwrd"&gt;void&lt;/span&gt; OnBeginningEdit(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, DataGridBeginningEditEventArgs e)
    {
      inEdit = &lt;span class="kwrd"&gt;true&lt;/span&gt;;
    }
    &lt;span class="kwrd"&gt;void&lt;/span&gt; OnCommittingEdit(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, DataGridEndingEditEventArgs e)
    {
      proxy.UpdateObject(e.Row.DataContext);
    }
    &lt;span class="kwrd"&gt;void&lt;/span&gt; OnGridKeyDown(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, KeyEventArgs e)
    {
      &lt;span class="kwrd"&gt;if&lt;/span&gt; ((e.Key == Key.Delete) &amp;amp;&amp;amp; (!inEdit))
      {
        &lt;span class="rem"&gt;// Single select for me.&lt;/span&gt;
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (dataGrid.SelectedItem != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
        {
          &lt;span class="rem"&gt;// Tell the DataServiceContext&lt;/span&gt;
          proxy.DeleteObject(dataGrid.SelectedItem);

          &lt;span class="rem"&gt;// Remove from the bound collection, disappears from&lt;/span&gt;
          &lt;span class="rem"&gt;// grid.&lt;/span&gt;
          BoundData.Remove(dataGrid.SelectedItem &lt;span class="kwrd"&gt;as&lt;/span&gt; Customers);
        }
      }
    }
    ObservableCollection&amp;lt;Customers&amp;gt; BoundData
    {
      get
      {
        &lt;span class="kwrd"&gt;return&lt;/span&gt; (dataGrid.DataContext &lt;span class="kwrd"&gt;as&lt;/span&gt; ObservableCollection&amp;lt;Customers&amp;gt;);
      }
    }&lt;/pre&gt;
&lt;p&gt;So, I've a form of update and a form of delete working. Insert can maybe be handlded by just pressing the Insert key, changing that handler to;&lt;/p&gt;&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;void&lt;/span&gt; OnGridKeyDown(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, KeyEventArgs e)
    {
      &lt;span class="kwrd"&gt;if&lt;/span&gt; (!inEdit)
      {
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (e.Key == Key.Delete)
        {
          &lt;span class="rem"&gt;// Single select for me.&lt;/span&gt;
          &lt;span class="kwrd"&gt;if&lt;/span&gt; (dataGrid.SelectedItem != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
          {
            &lt;span class="rem"&gt;// Tell the DataServiceContext&lt;/span&gt;
            proxy.DeleteObject(dataGrid.SelectedItem);

            &lt;span class="rem"&gt;// Remove from the bound collection, disappears from&lt;/span&gt;
            &lt;span class="rem"&gt;// grid.&lt;/span&gt;
            BoundData.Remove(dataGrid.SelectedItem &lt;span class="kwrd"&gt;as&lt;/span&gt; Customers);
          }
        }
        &lt;span class="kwrd"&gt;else&lt;/span&gt; &lt;span class="kwrd"&gt;if&lt;/span&gt; (e.Key == Key.Insert)
        {
          Customers c = &lt;span class="kwrd"&gt;new&lt;/span&gt; Customers() { Country = &lt;span class="str"&gt;"UK"&lt;/span&gt; };
          &lt;span class="kwrd"&gt;int&lt;/span&gt; index = BoundData.IndexOf(dataGrid.SelectedItem &lt;span class="kwrd"&gt;as&lt;/span&gt; Customers);
          BoundData.Insert(index, c);
          proxy.AddObject(&lt;span class="str"&gt;"Customers"&lt;/span&gt;, c);
        }
      }
    }&lt;/pre&gt;
&lt;p&gt;From there I think the next steps would be to think about inserting related entities ( 1 to many and many-to-many ), checking status codes, handling errors and so on. &lt;/p&gt;&lt;img src="http://mtaulty.com/CommunityServer/aggbug.aspx?PostID=10549" width="1" height="1"&gt;</description><category domain="http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/category/1000.aspx">.NET</category><category domain="http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/category/1005.aspx">ADO.NET</category><category domain="http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/category/1015.aspx">Silverlight</category><category domain="http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/category/1026.aspx">Data Access</category><category domain="http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/category/1027.aspx">Data Services</category></item><item><title>Silverlight and ADO.NET Data Services</title><link>http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2008/06/30/10548.aspx</link><pubDate>Mon, 30 Jun 2008 18:35:21 GMT</pubDate><guid isPermaLink="false">c62f47b3-9054-4265-9c0c-549d811810c2:10548</guid><dc:creator>mtaulty</dc:creator><slash:comments>5</slash:comments><comments>http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/comments/10548.aspx</comments><wfw:commentRss>http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/commentrss.aspx?PostID=10548</wfw:commentRss><description>&lt;p&gt;Someone mailed me to ask whether I had a video on how to put together Silverlight and ADO.NET Data Services.&lt;/p&gt; &lt;p&gt;I don't at the time of writing and I've also got a cold right now ( thank you, Microsoft Manchester office :-) ) so I thought I'd write something rather than record it.&lt;/p&gt; &lt;p&gt;Let's run through a step-by-step thing.&lt;/p&gt; &lt;p&gt;Visual Studio 2008 - File-&amp;gt;New-&amp;gt;Web Site. I'm going for the filesystem and C# as below;&lt;/p&gt; &lt;p&gt;&lt;a href="http://mtaulty.com/blog/images/SilverlightandADO.NETDataServices_AB4E/image.png"&gt;&lt;img height="183" alt="image" src="http://mtaulty.com/blog/images/SilverlightandADO.NETDataServices_AB4E/image_thumb.png" width="244" border="0"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;Now, to make it easy to work with ADO.NET Data Services, I'm going to add in an ADO.NET Entity Data Model for Northwind. That is ... Website-&amp;gt;Add-&amp;gt;New Item;&lt;/p&gt; &lt;p&gt;&lt;a href="http://mtaulty.com/blog/images/SilverlightandADO.NETDataServices_AB4E/image_3.png"&gt;&lt;img height="186" alt="image" src="http://mtaulty.com/blog/images/SilverlightandADO.NETDataServices_AB4E/image_thumb_3.png" width="244" border="0"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;I say "yes" to add it to my app_code folder, then select;&lt;/p&gt; &lt;p&gt;&lt;a href="http://mtaulty.com/blog/images/SilverlightandADO.NETDataServices_AB4E/image_4.png"&gt;&lt;img height="244" alt="image" src="http://mtaulty.com/blog/images/SilverlightandADO.NETDataServices_AB4E/image_thumb_4.png" width="241" border="0"&gt;&lt;/a&gt;&amp;nbsp;&lt;a href="http://mtaulty.com/blog/images/SilverlightandADO.NETDataServices_AB4E/image_5.png"&gt;&lt;img height="244" alt="image" src="http://mtaulty.com/blog/images/SilverlightandADO.NETDataServices_AB4E/image_thumb_5.png" width="241" border="0"&gt;&lt;/a&gt;&lt;a href="http://mtaulty.com/blog/images/SilverlightandADO.NETDataServices_AB4E/image_6.png"&gt;&lt;img height="244" alt="image" src="http://mtaulty.com/blog/images/SilverlightandADO.NETDataServices_AB4E/image_thumb_6.png" width="241" border="0"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;and then I can go and add a new ADO.NET Data Service ( again via Website-&amp;gt;Add New Item );&lt;/p&gt; &lt;p&gt;&lt;a href="http://mtaulty.com/blog/images/SilverlightandADO.NETDataServices_AB4E/image_7.png"&gt;&lt;img height="186" alt="image" src="http://mtaulty.com/blog/images/SilverlightandADO.NETDataServices_AB4E/image_thumb_7.png" width="244" border="0"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;and then I can update my service code to read;&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Service : DataService&amp;lt;NorthwindEntities&amp;gt;
{
  &lt;span class="rem"&gt;// This method is called only once to initialize service-wide policies.&lt;/span&gt;
  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; InitializeService(IDataServiceConfiguration config)
  {
    config.SetEntitySetAccessRule(&lt;span class="str"&gt;"*"&lt;/span&gt;, EntitySetRights.All);
  }
}&lt;/pre&gt;
&lt;p&gt;and I'm also going to reconfigure my project so that the built-in web server uses a particular port rather than a randomly selected one by selecting the website's properties and changing it;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://mtaulty.com/blog/images/SilverlightandADO.NETDataServices_AB4E/image_8.png"&gt;&lt;img height="161" alt="image" src="http://mtaulty.com/blog/images/SilverlightandADO.NETDataServices_AB4E/image_thumb_8.png" width="244" border="0"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Then I can add a new Silverlight 2 project here by doing File-&amp;gt;Add New Project;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://mtaulty.com/blog/images/SilverlightandADO.NETDataServices_AB4E/image_9.png"&gt;&lt;img height="181" alt="image" src="http://mtaulty.com/blog/images/SilverlightandADO.NETDataServices_AB4E/image_thumb_9.png" width="244" border="0"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;and then accepting the defaults for the Silverlight options;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://mtaulty.com/blog/images/SilverlightandADO.NETDataServices_AB4E/image_10.png"&gt;&lt;img height="207" alt="image" src="http://mtaulty.com/blog/images/SilverlightandADO.NETDataServices_AB4E/image_thumb_10.png" width="244" border="0"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Now, I need my Silverlight project to call the ADO.NET Data Service from my other project so I do a quick "view on browser" on my &lt;strong&gt;Service.svc&lt;/strong&gt; file just to spin up the web server. Then I can drop to a command line in my &lt;strong&gt;c:\demo\BlogPostSL&lt;/strong&gt; folder and use the &lt;strong&gt;datasvcutil.exe&lt;/strong&gt; tool to generate some proxy code for my Silverlight project;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://mtaulty.com/blog/images/SilverlightandADO.NETDataServices_AB4E/image_11.png"&gt;&lt;img height="193" alt="image" src="http://mtaulty.com/blog/images/SilverlightandADO.NETDataServices_AB4E/image_thumb_11.png" width="644" border="0"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Then I can pop back to Visual Studio and add this as an existing item to my Silverlight project. I also need to add a reference to;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;System.Data.Services.Client&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;in order to make that project ( with the new proxy code ) compile.&lt;/p&gt;
&lt;p&gt;Now, I want to build a little bit of UI for Silverlight to display some data. I want to use the &lt;strong&gt;DataGrid&lt;/strong&gt; so the first thing that I need to do is to add a reference to pick up the &lt;strong&gt;DataGrid&lt;/strong&gt; assembly as well. So, that's another reference to the Silverlight project;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;System.Windows.Controls.Data&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Now I can go and edit some XAML and build up a little piece of UI;&lt;/p&gt;&lt;pre class="csharpcode"&gt;&amp;lt;UserControl
  x:Class=&lt;span class="str"&gt;"BlogPostSL.Page"&lt;/span&gt;
  xmlns=&lt;span class="str"&gt;"http://schemas.microsoft.com/winfx/2006/xaml/presentation"&lt;/span&gt;
  xmlns:x=&lt;span class="str"&gt;"http://schemas.microsoft.com/winfx/2006/xaml"&lt;/span&gt;
  xmlns:data=&lt;span class="str"&gt;"clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"&lt;/span&gt;&amp;gt;
  &amp;lt;Grid x:Name=&lt;span class="str"&gt;"LayoutRoot"&lt;/span&gt; Background=&lt;span class="str"&gt;"White"&lt;/span&gt;&amp;gt;
    &amp;lt;Grid.RowDefinitions&amp;gt;
      &amp;lt;RowDefinition
        Height=&lt;span class="str"&gt;"8*"&lt;/span&gt; /&amp;gt;
      &amp;lt;RowDefinition /&amp;gt;
      &amp;lt;RowDefinition /&amp;gt;
    &amp;lt;/Grid.RowDefinitions&amp;gt;
    &amp;lt;data:DataGrid
      x:Name=&lt;span class="str"&gt;"dataGrid"&lt;/span&gt;
      Margin=&lt;span class="str"&gt;"10"&lt;/span&gt;
      AutoGenerateColumns=&lt;span class="str"&gt;"True"&lt;/span&gt;
      ItemsSource=&lt;span class="str"&gt;"{Binding}"&lt;/span&gt; /&amp;gt;
    &amp;lt;Button
      Margin=&lt;span class="str"&gt;"10"&lt;/span&gt;
      Content=&lt;span class="str"&gt;"Get Data"&lt;/span&gt;
      Grid.Row=&lt;span class="str"&gt;"1"&lt;/span&gt;
      Click=&lt;span class="str"&gt;"OnGetData"&lt;/span&gt; /&amp;gt;
  &amp;lt;/Grid&amp;gt;
&amp;lt;/UserControl&amp;gt;
&lt;/pre&gt;
&lt;p&gt;and then drop some code behind it;&lt;/p&gt;&lt;pre class="csharpcode"&gt;  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;partial&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Page : UserControl
  {
    &lt;span class="kwrd"&gt;public&lt;/span&gt; Page()
    {
      InitializeComponent();

      &lt;span class="kwrd"&gt;this&lt;/span&gt;.Loaded += OnLoaded;
    }
    &lt;span class="kwrd"&gt;void&lt;/span&gt; OnLoaded(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, RoutedEventArgs e)
    {
      proxy = &lt;span class="kwrd"&gt;new&lt;/span&gt; NorthwindEntities(
        &lt;span class="kwrd"&gt;new&lt;/span&gt; Uri(&lt;span class="str"&gt;"http://localhost:32767/BlogPost/Service.svc"&lt;/span&gt;, UriKind.Absolute));
    }
    &lt;span class="kwrd"&gt;void&lt;/span&gt; OnGetData(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, EventArgs args)
    {
      &lt;span class="rem"&gt;// I don't think that we can use LINQ here because there's no way then&lt;/span&gt;
      &lt;span class="rem"&gt;// to make it asynchronous. So, let's use the manual way of doing things.&lt;/span&gt;
      DataServiceQuery&amp;lt;Customers&amp;gt; query =
        proxy.CreateQuery&amp;lt;Customers&amp;gt;(&lt;span class="str"&gt;"Customers?$filter=Country eq 'UK'"&lt;/span&gt;);

      query.BeginExecute((asyncResult) =&amp;gt;
        {
          &lt;span class="kwrd"&gt;try&lt;/span&gt;
          {
            IEnumerable&amp;lt;Customers&amp;gt; result = query.EndExecute(asyncResult);

            &lt;span class="rem"&gt;// Doubt if we're on the UI thread so...&lt;/span&gt;
            Dispatcher.BeginInvoke(() =&amp;gt;
              {
                ObservableCollection&amp;lt;Customers&amp;gt; data = &lt;span class="kwrd"&gt;new&lt;/span&gt; ObservableCollection&amp;lt;Customers&amp;gt;();
                &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (Customers c &lt;span class="kwrd"&gt;in&lt;/span&gt; result)
                {
                  data.Add(c);
                }
                dataGrid.DataContext = data;
              });
          }
          &lt;span class="kwrd"&gt;catch&lt;/span&gt; (Exception ex)
          {
            &lt;span class="rem"&gt;// TODO&lt;/span&gt;
            Debugger.Break();
          }
        }, &lt;span class="kwrd"&gt;null&lt;/span&gt;);
    }
    NorthwindEntities proxy;
  }&lt;/pre&gt;
&lt;p&gt;and now clicking on my "Get Data" button gets me some data;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://mtaulty.com/blog/images/SilverlightandADO.NETDataServices_AB4E/image_12.png"&gt;&lt;img height="115" alt="image" src="http://mtaulty.com/blog/images/SilverlightandADO.NETDataServices_AB4E/image_thumb_12.png" width="644" border="0"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Now, that &lt;strong&gt;Orders&lt;/strong&gt; column isn't really something that I want so I guess the easiest thing to do there is to hide it. I still want the grid to automatically generate columns though so perhaps I can just get this one removed?&lt;/p&gt;&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; Page()
    {
      InitializeComponent();

      &lt;span class="kwrd"&gt;this&lt;/span&gt;.Loaded += OnLoaded;

      dataGrid.AutoGeneratingColumn += OnGeneratedColumn;
    }
    &lt;span class="kwrd"&gt;void&lt;/span&gt; OnGeneratedColumn(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, DataGridAutoGeneratingColumnEventArgs e)
    {
      &lt;span class="kwrd"&gt;if&lt;/span&gt; (e.Property.Name == &lt;span class="str"&gt;"Orders"&lt;/span&gt;)
      {
        e.Cancel = &lt;span class="kwrd"&gt;true&lt;/span&gt;;
      }
    }&lt;/pre&gt;
&lt;p&gt;That's a bit better in that I've got some data on the screen. &lt;/p&gt;
&lt;p&gt;As an aside, where I said in that code above that we "can't write this query with LINQ". That wasn't strictly true. I can write something like;&lt;/p&gt;&lt;pre class="csharpcode"&gt;      var query = (DataServiceQuery&amp;lt;Customers&amp;gt;)
        from c &lt;span class="kwrd"&gt;in&lt;/span&gt; proxy.Customers
        &lt;span class="kwrd"&gt;where&lt;/span&gt; c.Country == &lt;span class="str"&gt;"UK"&lt;/span&gt;
        select c;

      query.BeginExecute((asyncResult) =&amp;gt;
        { // .......
&lt;/pre&gt;
&lt;p&gt;and that looks to work fine once you get over the cast.&lt;/p&gt;
&lt;p&gt;I'll look at updating, inserting, deleting in subsequent posts otherwise this gets very long very quickly.&lt;/p&gt;&lt;img src="http://mtaulty.com/CommunityServer/aggbug.aspx?PostID=10548" width="1" height="1"&gt;</description><category domain="http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/category/1000.aspx">.NET</category><category domain="http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/category/1005.aspx">ADO.NET</category><category domain="http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/category/1015.aspx">Silverlight</category><category domain="http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/category/1026.aspx">Data Access</category><category domain="http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/category/1027.aspx">Data Services</category></item><item><title>Entity Framework - Timestamps and Concurrency</title><link>http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2008/06/26/10542.aspx</link><pubDate>Thu, 26 Jun 2008 16:30:56 GMT</pubDate><guid isPermaLink="false">c62f47b3-9054-4265-9c0c-549d811810c2:10542</guid><dc:creator>mtaulty</dc:creator><slash:comments>1</slash:comments><comments>http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/comments/10542.aspx</comments><wfw:commentRss>http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/commentrss.aspx?PostID=10542</wfw:commentRss><description>&lt;p&gt;Someone asked me today how you'd go about ensuring that timestamp columns in your database tables show up in your Entity Framework EDMX file with a &lt;strong&gt;Concurrency=Fixed&lt;/strong&gt; attribute on them.&lt;/p&gt; &lt;p&gt;That is - it's very likely that the timestamps are there on the table to enforce concurrency so why not default their &lt;strong&gt;Concurrency&lt;/strong&gt; value to "Fixed" ?&lt;/p&gt; &lt;p&gt;It's a good question but it's not something that the tooling does as far as I'm aware so I tried to have together some LINQ to XML code that would make an attempt at it. I don't claim that this is correct at all but it might be a starting point for this and similar, related pre-processing that you want to do on an EDMX file.&lt;/p&gt;&lt;pre class="csharpcode"&gt;  &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args)
  {
    XElement edmxFile = XElement.Load(args[0]);

    XNamespace edmxNs = XNamespace.Get(&lt;span class="str"&gt;"http://schemas.microsoft.com/ado/2007/06/edmx"&lt;/span&gt;);
    XNamespace ssdlNs = XNamespace.Get(&lt;span class="str"&gt;"http://schemas.microsoft.com/ado/2006/04/edm/ssdl"&lt;/span&gt;);
    XNamespace mapNs = XNamespace.Get(&lt;span class="str"&gt;"urn:schemas-microsoft-com:windows:storage:mapping:CS"&lt;/span&gt;);
    XNamespace csdlNs = XNamespace.Get(&lt;span class="str"&gt;"http://schemas.microsoft.com/ado/2006/04/edm"&lt;/span&gt;);

    var timestampCols =
      from ssdlProp &lt;span class="kwrd"&gt;in&lt;/span&gt; edmxFile.DescendantsAndSelf(ssdlNs + &lt;span class="str"&gt;"Property"&lt;/span&gt;)
      join mapProp &lt;span class="kwrd"&gt;in&lt;/span&gt; edmxFile.DescendantsAndSelf(mapNs + &lt;span class="str"&gt;"ScalarProperty"&lt;/span&gt;)
      on (&lt;span class="kwrd"&gt;string&lt;/span&gt;)ssdlProp.Attribute(&lt;span class="str"&gt;"Name"&lt;/span&gt;) equals (&lt;span class="kwrd"&gt;string&lt;/span&gt;)mapProp.Attribute(&lt;span class="str"&gt;"ColumnName"&lt;/span&gt;)       
      join csdlProp &lt;span class="kwrd"&gt;in&lt;/span&gt; edmxFile.DescendantsAndSelf(csdlNs + &lt;span class="str"&gt;"Property"&lt;/span&gt;)
      on (&lt;span class="kwrd"&gt;string&lt;/span&gt;)mapProp.Attribute(&lt;span class="str"&gt;"Name"&lt;/span&gt;) equals (&lt;span class="kwrd"&gt;string&lt;/span&gt;)csdlProp.Attribute(&lt;span class="str"&gt;"Name"&lt;/span&gt;)
      &lt;span class="kwrd"&gt;where&lt;/span&gt; (&lt;span class="kwrd"&gt;string&lt;/span&gt;)ssdlProp.Attribute(&lt;span class="str"&gt;"Type"&lt;/span&gt;) == &lt;span class="str"&gt;"timestamp"&lt;/span&gt; &amp;amp;&amp;amp; 
        (&lt;span class="kwrd"&gt;string&lt;/span&gt;)mapProp.Parent.Attribute(&lt;span class="str"&gt;"StoreEntitySet"&lt;/span&gt;) == (&lt;span class="kwrd"&gt;string&lt;/span&gt;)ssdlProp.Parent.Attribute(&lt;span class="str"&gt;"Name"&lt;/span&gt;) &amp;amp;&amp;amp;
        (&lt;span class="kwrd"&gt;string&lt;/span&gt;)mapProp.Ancestors(mapNs + &lt;span class="str"&gt;"EntitySetMapping"&lt;/span&gt;).First().Attribute(&lt;span class="str"&gt;"Name"&lt;/span&gt;) 
          == (&lt;span class="kwrd"&gt;string&lt;/span&gt;)csdlProp.Parent.Attribute(&lt;span class="str"&gt;"Name"&lt;/span&gt;)
      select csdlProp;

    &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var item &lt;span class="kwrd"&gt;in&lt;/span&gt; timestampCols)
    {
      item.SetAttributeValue(&lt;span class="str"&gt;"ConcurrencyMode"&lt;/span&gt;, &lt;span class="str"&gt;"Fixed"&lt;/span&gt;);
    }
    edmxFile.Save(args[0]);
  }
&lt;/pre&gt;
&lt;p&gt;I then used this inside of VS as a pre-build action to change my EDMX file prior to building the whole project. Seemed to work for my trivial example.&lt;/p&gt;
&lt;p&gt;Feel free to take, borrow, tweak, ignore :-) Just don't blame me ( of course ) if it breaks your EDMX file.&lt;/p&gt;&lt;img src="http://mtaulty.com/CommunityServer/aggbug.aspx?PostID=10542" width="1" height="1"&gt;</description><category domain="http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/category/1005.aspx">ADO.NET</category><category domain="http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/category/1024.aspx">Entity Framework</category></item><item><title>Michael Rys in London on Non-Relational Data in SQL Server</title><link>http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2008/06/25/10537.aspx</link><pubDate>Wed, 25 Jun 2008 14:51:36 GMT</pubDate><guid isPermaLink="false">c62f47b3-9054-4265-9c0c-549d811810c2:10537</guid><dc:creator>mtaulty</dc:creator><slash:comments>0</slash:comments><comments>http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/comments/10537.aspx</comments><wfw:commentRss>http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/commentrss.aspx?PostID=10537</wfw:commentRss><description>&lt;p&gt;The UK, SQL Server User Group has &lt;a href="http://blogs.msdn.com/mrys/"&gt;Michael Rys&lt;/a&gt; delivering a talk on Monday in London. Michael's a Program Manager in SQL Server.&lt;/p&gt; &lt;p&gt;&lt;a href="http://sqlserverfaq.com/?eid=126"&gt;Go here for the details&lt;/a&gt; and to sign up.&lt;/p&gt; &lt;p&gt;I don't know Michael personally but I know that back when I was looking at SQL Server 2005 and I asked any kind of question about the new XML data type it was more-often-than-not an email that came back from Michael with the answer in it so you should be in for a treat if you manage to get yourself signed up for this.&lt;/p&gt;&lt;img src="http://mtaulty.com/CommunityServer/aggbug.aspx?PostID=10537" width="1" height="1"&gt;</description><category domain="http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/category/1016.aspx">SQL Server</category><category domain="http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/category/1025.aspx">UK Communities</category></item></channel></rss>