<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
  <channel xmlns:blog="http://www.dotnetnuke.com/blog/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
    <title>Richard Waddell</title>
    <description>Richard Waddell - All About LightSwitch</description>
    <link>http://lightswitchhelpwebsite.com/Blog/tabid/61/BlogId/2/Default.aspx</link>
    <language>en-US</language>
    <webMaster>webmaster@adefwebserver.com</webMaster>
    <pubDate>Mon, 20 Apr 2026 03:29:18 GMT</pubDate>
    <lastBuildDate>Mon, 20 Apr 2026 03:29:18 GMT</lastBuildDate>
    <docs>http://backend.userland.com/rss</docs>
    <generator>Blog RSS Generator Version 4.0.0.0</generator>
    <item>
      <title>LightSwitch based Multi-Player Gaming Pattern using SignalR&amp;ndash;Part I</title>
      <link>http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/1213/LightSwitch-based-Multi-Player-Gaming-Pattern-using-SignalR.aspx</link>
      <description>&lt;h2&gt;Part I – Bare Bones Mechanics&lt;/h2&gt;  &lt;h2&gt;&lt;a title="Part II - Basic Classes and Interface Implementations" href="http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/1214/LightSwitch-based-Multi-Player-Gaming-Pattern-using-SignalR-ndash-Part-II.aspx" target="_blank"&gt;Part II - Basic Classes and Interface Implementations&lt;/a&gt;&lt;/h2&gt;  &lt;h2&gt;&lt;a href="http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/2228/LightSwitch-based-Multi-Player-Gaming-Pattern-using-SignalR-ndash-Part-III.aspx" target="_blank"&gt;Part III – Game to Demonstrate Derived Classes and more Sophisticated Interface Implementations&lt;/a&gt;&lt;/h2&gt;  &lt;h1&gt;The End Result&lt;/h1&gt;  &lt;p&gt;This article really starts when I start talking about motivation below, but I want to make the point up front that what I started out to do is not what I ended up doing. What I wanted to do was write some really cool simulations / games. What I ended up doing was writing what I hope is a really cool framework for designing / creating really cool simulations / games and a pretty mediocre game to demonstrate it. But I make lemonade out of that lemon by pointing out that a more complex game would obscure the details of how to use the framework.&lt;/p&gt;  &lt;p&gt;Anyhoo, here’s a screen shot of three users logged into the same page and all seeing the same thing but all able to interact with it individually. The idea behind the framework is you can plug in any kind of behavior you want for the simulation objects and rules engine.&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/1213/Windows-Live-Writer-3382ef8291a8_85CB-image_14.png"&gt;&lt;img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="/Portals/0/Blog/Files/2/1213/Windows-Live-Writer-3382ef8291a8_85CB-image_thumb.png" width="644" height="388" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h2&gt;Try It Out&lt;/h2&gt;  &lt;p&gt;You can try the game online at &lt;a title="http://sinalrgame1.lightswitchhelpwebsite.com/HTMLClient/" href="http://sinalrgame1.lightswitchhelpwebsite.com/HTMLClient/" target="_blank"&gt;http://sinalrgame1.lightswitchhelpwebsite.com/HTMLClient/&lt;/a&gt;&lt;/p&gt;  &lt;h1&gt;&lt;/h1&gt;  </description>
      <author>webmaster@adefwebserver.com</author>
      <comments>http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/1213/LightSwitch-based-Multi-Player-Gaming-Pattern-using-SignalR.aspx#Comments</comments>
      <slash:comments>0</slash:comments>
      <guid isPermaLink="true">http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/1213/LightSwitch-based-Multi-Player-Gaming-Pattern-using-SignalR.aspx</guid>
      <pubDate>Wed, 30 Oct 2013 00:00:00 GMT</pubDate>
      <trackback:ping>http://lightswitchhelpwebsite.comDesktopModules/BlogTrackback.aspx?id=1213</trackback:ping>
    </item>
    <item>
      <title>LightSwitch based Multi-Player Gaming Pattern using SignalR&amp;ndash;Part II</title>
      <link>http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/1214/LightSwitch-based-Multi-Player-Gaming-Pattern-using-SignalR-ndash-Part-II.aspx</link>
      <description>&lt;h3&gt;&lt;/h3&gt;  &lt;h3&gt;&lt;a href="http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/1213/LightSwitch-based-Multi-Player-Gaming-Pattern-using-SignalR.aspx" target="_blank"&gt;Part I – Bare Bones Mechanics&lt;/a&gt;&lt;/h3&gt;  &lt;h3&gt;Part II – Basic Classes and Interface Implementations&lt;/h3&gt;  &lt;h3&gt;&lt;a href="http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/2228/LightSwitch-based-Multi-Player-Gaming-Pattern-using-SignalR-ndash-Part-III.aspx" target="_blank"&gt;Part III – Game to Demonstrate Derived Classes and more Sophisticated Interface Implementations&lt;/a&gt;&lt;/h3&gt;  &lt;h2&gt;The End Result&lt;/h2&gt;  &lt;p&gt;The end result is not what I set out to do. I wanted to write games, but what I ended up with was so brittle it evolved into a game framework which I hope can be used to create all sorts of games.&lt;/p&gt;  &lt;p&gt;Here’s a screen shot of three users logged into the same page and all seeing the same thing but all able to interact with it individually. The intent of the framework is that you easily can plug in your own behavior and rules to control what comes out of that basic functionality.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/1214/Windows-Live-Writer-LightSwitch-based-Multi-Player-Gaming-Pa_9AE9-image1.png"&gt;&lt;img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="/Portals/0/Blog/Files/2/1214/Windows-Live-Writer-LightSwitch-based-Multi-Player-Gaming-Pa_9AE9-image1_thumb.png" width="644" height="390" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h2&gt;Try It Out&lt;/h2&gt;  &lt;p&gt;You can try the game online at &lt;a href="http://sinalrgame1.lightswitchhelpwebsite.com/HTMLClient/" target="_blank"&gt;http://sinalrgame1.lightswitchhelpwebsite.com/HTMLClient/&lt;/a&gt;&lt;/p&gt;  &lt;h1&gt;&lt;/h1&gt;  </description>
      <author>webmaster@adefwebserver.com</author>
      <comments>http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/1214/LightSwitch-based-Multi-Player-Gaming-Pattern-using-SignalR-ndash-Part-II.aspx#Comments</comments>
      <slash:comments>2</slash:comments>
      <guid isPermaLink="true">http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/1214/LightSwitch-based-Multi-Player-Gaming-Pattern-using-SignalR-ndash-Part-II.aspx</guid>
      <pubDate>Wed, 30 Oct 2013 00:00:00 GMT</pubDate>
      <trackback:ping>http://lightswitchhelpwebsite.comDesktopModules/BlogTrackback.aspx?id=1214</trackback:ping>
    </item>
    <item>
      <title>LightSwitch based Multi-Player Gaming Pattern using SignalR&amp;ndash;Part III</title>
      <link>http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/2228/LightSwitch-based-Multi-Player-Gaming-Pattern-using-SignalR-ndash-Part-III.aspx</link>
      <description>&lt;h3&gt;&lt;a href="http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/1213/LightSwitch-based-Multi-Player-Gaming-Pattern-using-SignalR.aspx" target="_blank"&gt;Part I – Bare Bones Mechanics&lt;/a&gt;&lt;/h3&gt;  &lt;h3&gt;&lt;a href="http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/1214/LightSwitch-based-Multi-Player-Gaming-Pattern-using-SignalR-ndash-Part-II.aspx" target="_blank"&gt;Part II – Basic Classes and Interface Implementations&lt;/a&gt;&lt;/h3&gt;  &lt;h3&gt;Part III - Game to Demonstrate Derived Classes and More Sophisticated Interface Implementations&lt;/h3&gt;  &lt;h1&gt;The End Result&lt;/h1&gt;  &lt;p&gt;The end result is a multi-player game that can be played across the internet by users logged into the same page. Unfortunately it’s not a very interesting game, and the question is still open as to whether I can in fact design an interesting game. What I have done, I hope, is to create a framework that can be used to design all sorts of interesting games. As such, a very simple game actually serves the purpose better as it exposes the details of using the framework to create alternative games and simulations and avoids obscuring them with details about the particular game. Maybe there will be a fourth post with an interesting game, but first we have to come up with a game lobby for this one, so who knows?&lt;/p&gt;  &lt;p&gt;The large graphic below shows a game in progress, so you can’t see the buttons used to enter the game, shown immediately below. Game play starts as soon as there are at least two players. You can see below that the game is in progress when Red player enters the game and gets the initial Notification “Click button to enter game”.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/2228/Windows-Live-Writer-LightSwitch-based-Multi-Player-Gaming-Pa_F984-image_15.png"&gt;&lt;img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="/Portals/0/Blog/Files/2/2228/Windows-Live-Writer-LightSwitch-based-Multi-Player-Gaming-Pa_F984-image_thumb_6.png" width="389" height="108" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The goal is to click on an opponent’s player so that your player moves on top. For this particular game, a point is awarded when you are successful, so, back on the Server, the behavior of the particular ooNaThing subtype, in conjunction with ooBerLink and ooBer, is to perform collision detection and increment its score if warranted. A different ooBerLink and ooNaThing might do something completely different, from handling the left mouse click to the consequences of collisions. There’s also nothing to prevent multiple ooNaThing subtypes, all interacting with each other. That’s the part &lt;em&gt;you&lt;/em&gt; can plug in.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/2228/Windows-Live-Writer-LightSwitch-based-Multi-Player-Gaming-Pa_F984-image_17.png"&gt;&lt;img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="/Portals/0/Blog/Files/2/2228/Windows-Live-Writer-LightSwitch-based-Multi-Player-Gaming-Pa_F984-image_thumb_7.png" width="644" height="390" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h2&gt;Try It Out&lt;/h2&gt;  &lt;p&gt;You can try the game online at &lt;a href="http://sinalrgame1.lightswitchhelpwebsite.com/HTMLClient/" target="_blank"&gt;http://sinalrgame1.lightswitchhelpwebsite.com/HTMLClient/&lt;/a&gt;&lt;/p&gt;  &lt;h1&gt;&lt;/h1&gt;  </description>
      <author>webmaster@adefwebserver.com</author>
      <comments>http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/2228/LightSwitch-based-Multi-Player-Gaming-Pattern-using-SignalR-ndash-Part-III.aspx#Comments</comments>
      <slash:comments>0</slash:comments>
      <guid isPermaLink="true">http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/2228/LightSwitch-based-Multi-Player-Gaming-Pattern-using-SignalR-ndash-Part-III.aspx</guid>
      <pubDate>Wed, 30 Oct 2013 00:00:00 GMT</pubDate>
      <trackback:ping>http://lightswitchhelpwebsite.comDesktopModules/BlogTrackback.aspx?id=2228</trackback:ping>
    </item>
    <item>
      <title>Joins and Left Outer Joins in LINQ&amp;ndash;Do you want groups with that?</title>
      <link>http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/183/Joins-and-Left-Outer-Joins-in-LINQ-ndash-Do-you-want-groups-with-that.aspx</link>
      <description>&lt;p&gt;&lt;strong&gt;LINQ joins, both inner and outer, are not always what they seem and how you go about it may depend on whether you want grouping.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Even for simple projects, I like to use LightSwitch for what I call Back Room screens because it’s just so darn convenient. You’ll see what I mean later, because these first two tables are so primitive, so uncouth, so crude that I don’t even call them tables – LightSwitch will attach to them but only as read-only. I call them MasterRowPile and ChildRowPile LightSwitch, as you will see, wants little to do with them because they have no primary keys. Brace yourselves, they are hideous to behold.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_2.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_thumb.png" width="644" height="185" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The purpose of these unrelated tables is to start with the simplest case and illustrate the differences as relationships are added.&lt;/p&gt;  &lt;p&gt;To set started I’m going to:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Create a manual relationship between the two tables by setting MasterRowID in ChildRowPile rows to match ID values in MasterRowPile rows. &lt;/li&gt;    &lt;li&gt;Show you two ways LINQ provides to join between the two&lt;/li&gt;    &lt;li&gt;Show you the T-SQL generated by the LINQ provider &lt;/li&gt;    &lt;li&gt;Show the Execution Plans generated by the T-SQL&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Since LightSwitch wouldn’t help me out, I had to use SSMS to enter values:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_4.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_thumb_1.png" width="644" height="263" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h1&gt;Inner and Outer Joins on Unrelated Tables &lt;/h1&gt;  &lt;p&gt;The tables shown above have no relationship as far as SQL is concerned, so any relationship is strictly by convention, meaning there is a column or columns on the ‘child’ table that is used to match a column or columns on the ‘master’ table. There are two ways to join these tables, using ‘join’, and using ‘where’&lt;/p&gt;  &lt;h3&gt;Join using ‘join’&lt;/h3&gt;  &lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; UnKeyedInnerJoinFromQuery()
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    ShowTitle("&lt;span style="color: #8b0000"&gt;UnKeyedInnerJoinFromQuery&lt;/span&gt;");
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; (RW_DataDataContext dc = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; RW_DataDataContext())
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        var query = from master &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; dc.MasterRowPiles
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                    join child &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; dc.ChildRowPiles
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                        on master.ID equals child.MasterRowID
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                    select &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; { MasterID = master.ID, Master = master.MasterRowName, ChildMasterID = child.MasterRowID, Child = child.ChildRowName };
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (var entity &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; query)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            Console.WriteLine("&lt;span style="color: #8b0000"&gt;{0} : {1} : {2} - {3}&lt;/span&gt;", entity.MasterID, entity.Master, entity.ChildMasterID, entity.Child);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;h3&gt;Join using ‘where’ (Equi-Join)&lt;/h3&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; UnKeyedEquiJoinFromQuery()
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    ShowTitle("&lt;span style="color: #8b0000"&gt;UnKeyedEquiJoinFromQuery&lt;/span&gt;");
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; (RW_DataDataContext dc = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; RW_DataDataContext())
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        var query = from master &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; dc.MasterRowPiles
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                    from child &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; dc.ChildRowPiles
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                    where master.ID == child.MasterRowID
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                    select &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; { MasterID = master.ID, Master = master.MasterRowName, ChildMasterID = child.MasterRowID, Child = child.ChildRowName };
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (var entity &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; query)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            Console.WriteLine("&lt;span style="color: #8b0000"&gt;{0} : {1} - {2} : {3}&lt;/span&gt;", entity.MasterID, entity.Master, entity.ChildMasterID, entity.Child);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;h3&gt;The Results&lt;/h3&gt;

&lt;p&gt;As we expect, we get a row for every master child combination and now rows for masters with no children.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_12.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_thumb_2.png" width="644" height="341" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;The T-SQL and Execution Plans&lt;/h3&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_26.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_thumb_5.png" width="890" height="772" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It turns out that both approaches generate very similar T-SQL and identical execution plans. &lt;/p&gt;

&lt;p&gt;So that takes care of the simple case. Not very interesting, and we’re not even going to look at the Extension Method syntax because it will come up later. We’re going to move on to Left Outer Joins on unrelated tables. This is where we get into whether to group or not to group.&lt;/p&gt;

&lt;h2&gt;Left Outer Join – Flattened Results&lt;/h2&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; UnKeyedLeftEquiJoinFromQuery()
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    ShowTitle("&lt;span style="color: #8b0000"&gt;UnKeyedLeftEquiJoinFromQuery&lt;/span&gt;");
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; (RW_DataDataContext dc = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; RW_DataDataContext())
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        var query = 
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        from master &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; dc.MasterRowPiles
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        from child &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; dc.ChildRowPiles
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            .Where(c =&gt; c.MasterRowID == master.ID)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            .DefaultIfEmpty()
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            select &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; 
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            { 
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                MasterID = master.ID, 
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                Master = master.MasterRowName, 
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                ChildMasterID = child.MasterRowID != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; ? child.MasterRowID : 0, 
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                Child = child.ChildRowName 
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            };
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (var entity &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; query)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            Console.WriteLine("&lt;span style="color: #8b0000"&gt;{0} : {1} - {2} : {3}&lt;/span&gt;", entity.MasterID, entity.Master, entity.ChildMasterID, entity.Child);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;This works because instead of the where keyword, I used the Where extension method to filter on the column values. This allowed me to apply the DefaultIfEmpty extension method to provide a default / empty child object if none exist on the database. That’s all it takes to convert an inner join to a left outer join.&lt;/p&gt;

&lt;p&gt;As expected, we get not only the masters with children, but one row for each master that doesn’t have a child. I had to accommodate the constraint that null can’t be assigned to ChildMasterID, our first complication from dealing with results of Left Outer Joins. We’ll get into that more later.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_38.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_thumb_8.png" width="644" height="245" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Left Outer Join – Grouped Results&lt;/h2&gt;

&lt;p&gt;This is similar to the inner join up until the into keyword. At that point one group is created for every master row and linked to a collection of child rows associated with that group. If there are no child rows the collection is empty, but the group still exists.&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; LeftJoinUnkeyedUsingIntoFromQuery()
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    ShowTitle("&lt;span style="color: #8b0000"&gt;LeftJoinUnkeyedUsingIntoFromQuery&lt;/span&gt;");
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; (RW_DataDataContext dc = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; RW_DataDataContext())
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        var query = 
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            from master &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; dc.MasterRowPiles
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            join child &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; dc.ChildRowPiles
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                on master.ID equals child.MasterRowID
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            into children
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            select &lt;span style="color: #0000ff"&gt;new&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                Master = master.MasterRowName,
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                Children = children
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            };
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (var group &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; query)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            Console.WriteLine(group.Master);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (var child &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; group.Children)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                Console.WriteLine("&lt;span style="color: #8b0000"&gt;{0} - {1} &lt;/span&gt;", child.MasterRowID, child.ChildRowName);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;The program output shows the grouping:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_42.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_thumb_12.png" width="644" height="383" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;T-SQL From the Left Outer Join using the ‘into’ keyword&lt;/h2&gt;

&lt;p&gt;I’m going to show you the T-SQL, but first I want to show you how I get it from Visual studio, so I’m going to show you each step I’m taking to get the T-SQL that will be generated by the query above:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Place your cursor on a line after the IQueryable you’re interested in and select ‘Run To Cursor’. In the following, I’m going to inspect ‘query’ using the Debugging Visualizer, so I place my cursor on the ‘foreach’ line, right-click, and select ‘Run To Cursor’&lt;/li&gt;

  &lt;li&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_44.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_thumb_18.png" width="462" height="484" /&gt;&lt;/a&gt;&lt;/li&gt;

  &lt;li&gt;When the line is hit, hover your cursor over ‘query’ and a tooltip will appear:&lt;/li&gt;

  &lt;li&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_46.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_thumb_20.png" width="644" height="294" /&gt;&lt;/a&gt;&lt;/li&gt;

  &lt;li&gt;Click on SELECT in the tooltip and the textbox will open up.&lt;/li&gt;

  &lt;li&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_48.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_thumb_21.png" width="644" height="249" /&gt;&lt;/a&gt;&lt;/li&gt;

  &lt;li&gt; Hit ctl-a / ctl-c to copy the contents.&lt;/li&gt;

  &lt;li&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_52.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_thumb_23.png" width="644" height="238" /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And here’s the T-SQL:&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{&lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=SELECT&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;SELECT&lt;/a&gt; [t0].[MasterRowName] &lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=AS&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;AS&lt;/a&gt; [Master], [t1].[ChildRowName], [t1].[MasterRowID], (
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=SELECT&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;SELECT&lt;/a&gt; &lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=COUNT&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;COUNT&lt;/a&gt;(*)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=FROM&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;FROM&lt;/a&gt; [dbo].[ChildRowPile] &lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=AS&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;AS&lt;/a&gt; [t2]
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=WHERE&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;WHERE&lt;/a&gt; [t0].[ID] = [t2].[MasterRowID]
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    ) &lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=AS&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;AS&lt;/a&gt; [&lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=value&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;value&lt;/a&gt;]
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=FROM&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;FROM&lt;/a&gt; [dbo].[MasterRowPile] &lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=AS&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;AS&lt;/a&gt; [t0]
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=LEFT&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;LEFT&lt;/a&gt; &lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=OUTER&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;OUTER&lt;/a&gt; &lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=JOIN&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;JOIN&lt;/a&gt; [dbo].[ChildRowPile] &lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=AS&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;AS&lt;/a&gt; [t1] &lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=ON&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;ON&lt;/a&gt; [t0].[ID] = [t1].[MasterRowID]
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Now I’m a little confused at this point, because if I execute that T-SQL in SSMS I see flattened rows:&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_54.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_thumb_24.png" width="644" height="313" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If I look at the output from the LINQ in LINQPad in rich text format I see grouping:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_62.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_thumb_28.png" width="552" height="484" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If I view it in LINQPad grid view:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_64.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_thumb_29.png" width="208" height="143" /&gt;&lt;/a&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_68.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_thumb_31.png" width="244" height="68" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But LINQPad sees the same T-SQL and yields the same results when you run it:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_70.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_thumb_32.png" width="644" height="465" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So there’s more going on here than is revealed in the T-SQL. As a matter of fact, Later we’ll look at GroupJoin(), which is the underlying extension method to see if we can figure out what’s going on. For now it’s enough to know the ‘join into’ approach will give you left outer join results, but grouped.&lt;/p&gt;

&lt;p&gt;Let’s go back and look at the T-SQL generated by the method that gave us the flattened results:&lt;/p&gt;

&lt;h2&gt;T-SQL From the Left Outer Join using the Where and DefaultIfEmpty LINQ Extension Methods&lt;/h2&gt;

&lt;p&gt;It’s doing the same left outer join as the T-SQL we saw above generated by the join into approach. The only differences are the CASE statement that is preventing the NULL assignment, which is an implementation detail. The other difference is that the ‘join into’ T-SQL was saving the count of child rows as can be seen in the value column above. I assume that is to facilitate stepping through the ‘groups’.&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=SELECT&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;SELECT&lt;/a&gt; [t0].[ID] &lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=AS&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;AS&lt;/a&gt; [MasterID], [t0].[MasterRowName] &lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=AS&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;AS&lt;/a&gt; [Master], 
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    (&lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=CASE&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;CASE&lt;/a&gt; 
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=WHEN&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;WHEN&lt;/a&gt; ([t1].[MasterRowID]) &lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=IS&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;IS&lt;/a&gt; &lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=NOT&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;NOT&lt;/a&gt; &lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=NULL&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;NULL&lt;/a&gt; &lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=THEN&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;THEN&lt;/a&gt; [t1].[MasterRowID]
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=ELSE&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;ELSE&lt;/a&gt; @p0
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;     &lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=END&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;END&lt;/a&gt;) &lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=AS&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;AS&lt;/a&gt; [ChildMasterID], [t1].[ChildRowName] &lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=AS&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;AS&lt;/a&gt; [Child]
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=FROM&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;FROM&lt;/a&gt; [dbo].[MasterRowPile] &lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=AS&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;AS&lt;/a&gt; [t0]
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=LEFT&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;LEFT&lt;/a&gt; &lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=OUTER&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;OUTER&lt;/a&gt; &lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=JOIN&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;JOIN&lt;/a&gt; [dbo].[ChildRowPile] &lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=AS&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;AS&lt;/a&gt; [t1] &lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=ON&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;ON&lt;/a&gt; [t1].[MasterRowID] = [t0].[ID]
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Note the zero I specified as the null replacement assignment to MasterRowID is parameterized in the resultant T-SQL. After substituting a zero and running the query in SSMS I see what I would expect:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_72.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_thumb_33.png" width="644" height="330" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It turns out that the extension method generated when two ‘froms’ are used like this is SelectMany. So it seems that GroupJoin and SelectMany both do left outer joins, but GroupJoin groups the results and SelectMany leaves them flattened. We’ll look more closely later on.&lt;/p&gt;

&lt;p&gt;Right now, let’s look at the difference when joining related tables.&lt;/p&gt;

&lt;h1&gt;Inner and Outer Joins on Related Tables&lt;/h1&gt;

&lt;p&gt;I have a pair of existing tables, Departments and Employees&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_74.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_thumb_34.png" width="644" height="222" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Employees.DepartmentID is a foreign key pointing to Departments.ID. Each Department can be said to have a collection of zero or more Employees, as a Department may exist that has no Employees. &lt;/p&gt;

&lt;p&gt;LightSwitch likes these tables just fine, so I can use it to show you the values in the tables.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_76.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_thumb_35.png" width="405" height="484" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s begin with an inner join that will be the basis of our left outer join.&lt;/p&gt;

&lt;h2&gt;Inner Join on Related Tables&lt;/h2&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; InnerJoinOnCollectionFromQuery()
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #008000"&gt;// Same Result as EquiJoin&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    ShowTitle("&lt;span style="color: #8b0000"&gt;InnerJoinOnCollectionFromQuery&lt;/span&gt;");
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; (RW_DataDataContext dc = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; RW_DataDataContext())
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        var query = from dept &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; dc.Departments
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                    from emp &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; dept.Employees
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                    select &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; { emp.Name, Department = dept.Name };
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (var emp &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; query)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            Console.WriteLine("&lt;span style="color: #8b0000"&gt;{0} - {1}&lt;/span&gt;", emp.Name, emp.Department);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;The difference is in the second ‘from’, which is using dot notation to get to the collection of Employees linked to the current Department. It turns out the T-SQL is exactly the same, but I think this code is more elegant than using a where to filter all Employees. And it definitely makes the left outer join easier.&lt;/p&gt;

&lt;p&gt;As we’d expect for an inner join, we only get rows for Departments that have Employees:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_78.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_thumb_36.png" width="644" height="316" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And the T-SQL shows we’re actually getting an Equi-Join, which as we’ve already seen, generates exactly the same execution plan as an inner join.&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{&lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=SELECT&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;SELECT&lt;/a&gt; [t1].[Name], [t0].[Name] &lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=AS&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;AS&lt;/a&gt; [Department]
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=FROM&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;FROM&lt;/a&gt; [dbo].[Departments] &lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=AS&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;AS&lt;/a&gt; [t0], [dbo].[Employees] &lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=AS&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;AS&lt;/a&gt; [t1]
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=WHERE&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;WHERE&lt;/a&gt; [t1].[DepartmentID] = [t0].[ID]
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Although now it can take advantage of the primary keys and relationship between the tables, just as the inner join would:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_80.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_thumb_37.png" width="644" height="277" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Left Outer Join on Related Tables&lt;/h2&gt;

&lt;p&gt;We only have to modify our inner join query slightly to convert it to a left outer join. In fact, we only have to add one extension method, DefaultIfEmpty. Because our dept.Employees collection is already limited to Employees in the current department, we can just slap the DefaultIfEmpty() method directly onto the collection:&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; LeftJoinUsingCollectionFromQuery()
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    ShowTitle("&lt;span style="color: #8b0000"&gt;LeftJoinUsingCollectionFromQuery&lt;/span&gt;");
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; (RW_DataDataContext dc = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; RW_DataDataContext())
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        var query = from dept &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; dc.Departments
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                    from emp &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; dept.Employees.DefaultIfEmpty()
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                    select &lt;span style="color: #0000ff"&gt;new&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                    {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                        Department = dept.Name,
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                        Employee = emp.Name
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                    };
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (var emp &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; query)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            Console.WriteLine("&lt;span style="color: #8b0000"&gt;{0} - {1}&lt;/span&gt;", emp.Department, emp.Employee);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;And sure enough, rows for every Department, including the ones with no Employees&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_82.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_thumb_38.png" width="644" height="290" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The T-SQL is just a straightforward left outer join:&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=SELECT&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;SELECT&lt;/a&gt; [t0].[Name] &lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=AS&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;AS&lt;/a&gt; [Department], [t1].[Name] &lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=AS&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;AS&lt;/a&gt; [Employee]
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=FROM&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;FROM&lt;/a&gt; [dbo].[Departments] &lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=AS&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;AS&lt;/a&gt; [t0]
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=LEFT&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;LEFT&lt;/a&gt; &lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=OUTER&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;OUTER&lt;/a&gt; &lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=JOIN&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;JOIN&lt;/a&gt; [dbo].[Employees] &lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=AS&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;AS&lt;/a&gt; [t1] &lt;a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=ON&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99"&gt;ON&lt;/a&gt; [t1].[DepartmentID] = [t0].[ID]&lt;/pre&gt;&lt;/pre&gt;

&lt;h2&gt;Grouped Left Outer Join On Related Tables Using the ‘join into’ Approach&lt;/h2&gt;

&lt;p&gt;I’m only showing you this because later we’ll want to compare the Extension Method Syntax, which hereafter I’m just going to call ‘Lambda Syntax’&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; LeftJoinUsingIntoFromQuery()
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    ShowTitle("&lt;span style="color: #8b0000"&gt;LeftJoinUsingIntoFromQuery&lt;/span&gt;");
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; (RW_DataDataContext dc = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; RW_DataDataContext())
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        var query = from dept &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; dc.Departments
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                    join emp &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; dc.Employees
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                    on
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                        dept.ID equals emp.DepartmentID
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                        into ed
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                    select &lt;span style="color: #0000ff"&gt;new&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                    {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                        Department = dept.Name,
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                        Employees = ed
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                    };
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (var group &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; query)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            Console.WriteLine(group.Department);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (var emp &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; group.Employees)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                Console.WriteLine("&lt;span style="color: #8b0000"&gt;  &lt;/span&gt;" + emp.Name);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;The results have groups for every master row and collections of employees under each Department that has Employees:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_84.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_thumb_39.png" width="644" height="404" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The T-SQL is what we expect, with a column for the count of employees in each group.&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;SELECT [t0].[Name] AS [Department], [t1].[ID], [t1].[Name], [t1].[Salary], [t1].[DepartmentID], (
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    SELECT COUNT(*)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    FROM [dbo].[Employees] AS [t2]
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    WHERE [t0].[ID] = [t2].[DepartmentID]
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    ) AS [&lt;span style="color: #0000ff"&gt;value&lt;/span&gt;]
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;FROM [dbo].[Departments] AS [t0]
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;LEFT OUTER JOIN [dbo].[Employees] AS [t1] ON [t0].[ID] = [t1].[DepartmentID]
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;ORDER BY [t0].[ID], [t1].[ID]&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;And the output from the T-SQL:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_86.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_thumb_40.png" width="644" height="248" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Actually I can see now that the grouping is achieved by parsing the flattened output.&lt;/p&gt;

&lt;h1&gt;LINQ Extension Method Syntax&lt;/h1&gt;

&lt;p&gt;To understand the difference between the flattened and grouped results, we need to understand the function of the Extension Methods used in Lambda Syntax. Lambda syntax is always generated and passed to IQueryable as Func&lt;&gt; and Action&lt;&gt; delegates wrapped in Expressions, so even if we write the query in Comprehension syntax, understanding the Extension Method that actually gets called is key.&lt;/p&gt;

&lt;p&gt;In the case of the successive from keywords in the Comprehension syntax query, the Extension Method is SelectMany()&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; LeftJoinUsingCollectionFromLambda()
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    ShowTitle("&lt;span style="color: #8b0000"&gt;LeftJoinUsingCollectionFromLambda&lt;/span&gt;");
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; (RW_DataDataContext dc = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; RW_DataDataContext())
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        var query = 
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        dc.Departments
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        .SelectMany
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        (
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            dept =&gt; dept.Employees.DefaultIfEmpty(),
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            (dept, emp) =&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; 
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                Department = dept.Name,
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                Employee = emp.Name
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        );
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (var emp &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; query)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            Console.WriteLine("&lt;span style="color: #8b0000"&gt;{0} - {1}&lt;/span&gt;", emp.Department, emp.Employee);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;In the case of the ‘join into’ approach in the Comprehension syntax query, the Extension Method is GroupJoin()&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; LeftJoinUsingIntoFromLambda()
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    ShowTitle("&lt;span style="color: #8b0000"&gt;LeftJoinUsingIntoFromLambda&lt;/span&gt;");
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; (RW_DataDataContext dc = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; RW_DataDataContext())
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        var query = 
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        dc.Departments
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            .GroupJoin
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            (
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                dc.Employees,
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                dept =&gt; (Int32?)(dept.ID),
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                emp =&gt; emp.DepartmentID,
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                (d, emps) =&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                &lt;span style="color: #0000ff"&gt;new&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                    Department = d.Name,
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                    Employees = emps
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            );
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (var group &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; query)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            Console.WriteLine(group.Department);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (var emp &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; group.Employees)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                Console.WriteLine("&lt;span style="color: #8b0000"&gt;  &lt;/span&gt;" + emp.Name);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;h1&gt;SelectMany() and GroupJoin() LINQ Extension Methods&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/bb549040.aspx" target="_blank"&gt;Queryable.SelectMany() Documentation&lt;/a&gt;&lt;/li&gt;

  &lt;ul&gt;
    &lt;li&gt;Queryable.SelectMany&lt;TSource, TCollection, TResult&gt;&lt;/li&gt;

    &lt;li&gt;“Projects each element of a sequence to an &lt;a href="http://msdn.microsoft.com/en-us/library/9eekhta0.aspx"&gt;IEnumerable&lt;T&gt;&lt;/a&gt; and invokes a result selector function on each element therein. The resulting values from each intermediate sequence are combined into a single, one-dimensional sequence and returned.’&lt;/li&gt;

    &lt;li&gt;The Enumerable.SelectMany descriiption is a little easier to understand – “Projects each element of a sequence to an &lt;a href="http://msdn.microsoft.com/en-us/library/9eekhta0.aspx"&gt;IEnumerable&lt;T&gt;&lt;/a&gt; and flattens the resulting sequences into one sequence”&lt;/li&gt;
  &lt;/ul&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;font face="Tahoma"&gt;Yeah, Yeah, but how does it work. To make the lambda syntax a little easier to follow, In the comprehension query I did something I normally never do, which was to use one letter variable names that would be spread over more than one line of code. Since there’s only c and d, it’s clear what’s being referred to, and it makes them easier to follow in the lambda syntax query. Here it is as generated by LINQPad&lt;/font&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_88.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_thumb_41.png" width="644" height="302" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;font face="Tahoma"&gt;So that’s not too bad. Each department ‘goes to’ a collection of department employees. For each member in that collection, department and employee ‘go to’ an anonymous type object with department and employee name.&lt;/font&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.linq.queryable.groupjoin.aspx" target="_blank"&gt;Queryable.GroupJoin().Documentation&lt;/a&gt;&lt;/li&gt;

  &lt;ul&gt;
    &lt;li&gt;Queryable.GroupJoin&lt;TOuter, TInner, Tkey, TResult&gt;&lt;/li&gt;

    &lt;li&gt;“Correlates the elements of two sequences based on key equality and groups the results.”&lt;/li&gt;

    &lt;li&gt;The Enumerable.GroupJoin description is the same&lt;/li&gt;
  &lt;/ul&gt;
&lt;/ul&gt;

&lt;p&gt;Here’s the ‘join into’ Lambda with one character variable names&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_90.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_thumb_42.png" width="550" height="484" /&gt;&lt;/a&gt;&lt;/p&gt;





&lt;p&gt;Not too bad, I think. Here goes. From Departments join to Employees. Join on Department.ID and Employee.DepartmentID. The output consists of the Department Name and the Employees Collection of all the Employees where Employee.DepartmentID matches Department.ID. As we’ve seen this results in T-SQL that puts out a flattened result set with a column for the count of Employees in each group. &lt;/p&gt;

&lt;h1&gt;Where’s The LightSwitch?&lt;/h1&gt;

&lt;p&gt;You have me there. Hopefully the need for LINQ in LightSwitch and WCF RIA services and everywhere else will justify posting this here.&lt;/p&gt;

&lt;p&gt;I will tell you this. If you attach to a table that has a nullable foreign key, LightSwitch will see that as a zero-or-one to many relationship, as it should. But if you later make that foreign-key column non-nullable your screens will stop working. If you then rebuild the entire solution you’ll get an error&lt;/p&gt;

&lt;h2&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_100.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_thumb_47.png" width="1028" height="102" /&gt;&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;However it is not possible to edit the relationship.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_102.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/183/Windows-Live-Writer-Joins-Equ-Joins-Left-Outer-Joins-and-Gro_EB29-image_thumb_48.png" width="524" height="484" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So you’re stuck with it unless you do some deleting, which always promises / threatens to delete all related code, so that’s a hassle.&lt;/p&gt;

&lt;h1&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;If you want a flattened result set from your left outer join, use the multiple from approach in your Comprehension Query to generate the SelectMany() Extension Method. Otherwise use ‘join into’ to generate the GroupJoin extension method which will give you grouped results. &lt;/p&gt;&lt;br /&gt;&lt;a href=http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/183/Joins-and-Left-Outer-Joins-in-LINQ-ndash-Do-you-want-groups-with-that.aspx&gt;More ...&lt;/a&gt;</description>
      <author>webmaster@adefwebserver.com</author>
      <comments>http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/183/Joins-and-Left-Outer-Joins-in-LINQ-ndash-Do-you-want-groups-with-that.aspx#Comments</comments>
      <slash:comments>6</slash:comments>
      <guid isPermaLink="true">http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/183/Joins-and-Left-Outer-Joins-in-LINQ-ndash-Do-you-want-groups-with-that.aspx</guid>
      <pubDate>Sat, 02 Mar 2013 20:16:34 GMT</pubDate>
      <trackback:ping>http://lightswitchhelpwebsite.comDesktopModules/BlogTrackback.aspx?id=183</trackback:ping>
    </item>
    <item>
      <title>Rescue Legacy Data using LightSwitch, Stored Procedures, and Dynamic SQL, Part 1</title>
      <link>http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/177/Rescue-Legacy-Data-using-LightSwitch-Stored-Procedures-and-Dynamic-SQL.aspx</link>
      <description>&lt;p&gt; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/177/Windows-Live-Writer-4195ad925031_8009-image_117.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/177/Windows-Live-Writer-4195ad925031_8009-image_thumb_51.png" width="644" height="484" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;LightSwitch provides for creating Data Sources in several ways. In the case of an existing database you would typically either specify the database itself or a WCF RIA Service.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/177/Windows-Live-Writer-4195ad925031_8009-image_2.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/177/Windows-Live-Writer-4195ad925031_8009-image_thumb.png" width="644" height="339" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;But sometimes neither is feasible. I was confronted with a database with no primary keys and incredibly wide tables – so wide that I got error messages about it. And you can’t really do much with a database that has no primary keys. Also modifying the schema was not an option.&lt;/p&gt;  &lt;p&gt;This actually turned out to be quite liberating. The reason we wanted to access the database outside of the legacy application it was designed for was to&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Provide views of the data that the legacy application did not. &lt;/li&gt;    &lt;li&gt;Add additional columns &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;By extracting the data into another database we could&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Eliminate literally hundreds of columns (Yes, I do mean literally) &lt;/li&gt;    &lt;li&gt;Create primary keys &lt;/li&gt;    &lt;li&gt;Create relationships with referential integrity through foreign keys &lt;/li&gt; &lt;/ul&gt;  </description>
      <author>webmaster@adefwebserver.com</author>
      <comments>http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/177/Rescue-Legacy-Data-using-LightSwitch-Stored-Procedures-and-Dynamic-SQL.aspx#Comments</comments>
      <slash:comments>6</slash:comments>
      <guid isPermaLink="true">http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/177/Rescue-Legacy-Data-using-LightSwitch-Stored-Procedures-and-Dynamic-SQL.aspx</guid>
      <pubDate>Sat, 09 Feb 2013 07:51:20 GMT</pubDate>
      <trackback:ping>http://lightswitchhelpwebsite.comDesktopModules/BlogTrackback.aspx?id=177</trackback:ping>
      <blog:tag blog:url="http://lightswitchhelpwebsite.com/Blog/tabid/61/TagID/14/Default.aspx">LightSwitch</blog:tag>
      <blog:tag blog:url="http://lightswitchhelpwebsite.com/Blog/tabid/61/TagID/43/Default.aspx">Dynamic SQL</blog:tag>
      <blog:tag blog:url="http://lightswitchhelpwebsite.com/Blog/tabid/61/TagID/44/Default.aspx">Stored Procedures</blog:tag>
    </item>
    <item>
      <title>Levels of Validation and Filtering on User Membership</title>
      <link>http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/78/Levels-of-Validation-and-Filtering-on-User-Membership.aspx</link>
      <description>&lt;p&gt; &lt;/p&gt;  &lt;h1&gt;Many-to-Many Relationships&lt;/h1&gt;  &lt;p&gt;A typical validation task that involves a many-to-many relationship involves a User who can update a number of Entities and an Entity that can be updated by a number of Users. For instance a School Book Inventory system where the counts for books at a particular school can only be updated by an employee of that school. Each employee can update a number of counts and each count can be updated by a number of employees. The application must prevent unauthorized data base updates and prevent employees from seeing counts from other schools.&lt;/p&gt;  &lt;p&gt;We’ll start with validation. Although this article touches on validation on both client and server, to really understand what’s going on I suggest you &lt;a href="http://blogs.msdn.com/b/lightswitch/archive/2010/08/30/overview-of-data-validation-in-lightswitch-applications-prem-ramanathan.aspx" target="_blank"&gt;see this post&lt;/a&gt; by Prem Ramanathan and this &lt;a href="http://www.code-magazine.com/articleprint.aspx?quickid=1105091&amp;printmode=true" target="_blank"&gt;article he wrote for Code magazine&lt;/a&gt;. And if you want to get into what you can do in the Save Pipeline, which is entered when you call this.ApplicationData.SaveChanges(), either through code or when the save button is executed, &lt;a href="http://www.code-magazine.com/Article.aspx?quickid=1103071" target="_blank"&gt;check out this article by Dan Seefeldt&lt;/a&gt;.&lt;/p&gt;  &lt;h1&gt;The Requirements&lt;/h1&gt;  &lt;p&gt;As I said, the example is based on maintenance of book inventory for a number of schools within a school district. The inventory records for all books are maintained in a single table and each school is responsible for maintaining the counts for the books at that school. The requirements:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Don’t allow an employee of one school to update the counts from a different school &lt;/li&gt;    &lt;li&gt;Don’t allow invalid counts &lt;/li&gt;    &lt;li&gt;Don’t allow a particular book to be assigned to a particular school twice &lt;/li&gt;    &lt;li&gt;Don’t allow an employee of one school to see the counts from a different school &lt;/li&gt;    &lt;li&gt;Validate counts at the screen level &lt;/li&gt; &lt;/ul&gt;  &lt;h1&gt;The Tables&lt;/h1&gt;  &lt;p&gt;We start by creating a Book entity.  Turn off ‘Display by Default’ for Id (and for Id on all other entities we create). Turn on ‘Include in Unique Index’ for Title.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_2.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_thumb.png" width="644" height="376" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Next we have a School entity. Turn on ‘Include in Unique Index’ for Name.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_4.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_thumb_1.png" width="644" height="350" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h1&gt;The Relationships&lt;/h1&gt;  &lt;p&gt;A School has many Books and a Book can be at many Schools, so we need a many-to-many relationship between School and Book. Create a SchoolBook table as shown below. Note the relationships. Each SchoolBook is related to one School and one Book. By including both School and Book in unique index we ensure there is only one SchoolBook record for any particular Book at a particular School. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_8.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_thumb_3.png" width="644" height="359" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;For display purposes we add a Summary property which is computed:&lt;/p&gt;  &lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;namespace&lt;/span&gt; LightSwitchApplication
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; partial &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; SchoolBook
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        partial &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Summary_Compute(&lt;span style="color: #0000ff"&gt;ref&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; result)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            result = &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Format("&lt;span style="color: #8b0000"&gt;{0} / {1}&lt;/span&gt;",
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                School != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; ? School.Name : "&lt;span style="color: #8b0000"&gt;&lt;/span&gt;",
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                Book != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; ? Book.Title : "&lt;span style="color: #8b0000"&gt;&lt;/span&gt;");
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;h1&gt;The Screens&lt;/h1&gt;

&lt;p&gt;About the screen names – I’ve been working on a project with a lot of tables that required a lot of validation and it was helpful to create what I call a Debug Screen for each entity to easily test before and after, switch back and forth, etc. Turns out not so useful here but what’s the harm, and tempus is fugiting, so I’m sticking with the names.&lt;/p&gt;

&lt;p&gt;We’ll create DebugBooks, DebugSchools, and DebugSchoolBooks List and Detail screens. Be sure to include all Additional Data for all three screens.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_10.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_thumb_4.png" width="610" height="484" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;The Data&lt;/h1&gt;

&lt;p&gt;Now hit ctl-F5 to run the application and let’s see what we have.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_16.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_thumb_7.png" width="644" height="293" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We add some Books above and some Schools below:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_18.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_thumb_8.png" width="644" height="240" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;SchoolBook Validation&lt;/h1&gt;

&lt;p&gt;Now I’ll just point out here that if you add a SchoolBook relationship through the Books screen you’ll be constrained to the selected Book; the Schools screen will constrain you on the selected School. The School Books screen constrains neither, as shown below:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_20.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_thumb_9.png" width="644" height="351" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And we confirm we can add more than one book to Riverdale High, but we can’t add the same book twice:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_22.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_thumb_10.png" width="644" height="285" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;Adding Users&lt;/h1&gt;

&lt;p&gt;Now we’ll add a SchoolEmployee entity and some School Employees to maintain the Counts:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_12.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_thumb_5.png" width="644" height="421" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We have a User property as we are going to match to logged-in User. It’s a business rule that a School Employee can only be employed at one School, so we  make User the one and only field to ‘Include in Unique Index’. &lt;/p&gt;

&lt;p&gt;Now let’s run the app and add a SchoolEmployee:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_14.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_thumb_6.png" width="644" height="221" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you run under Visual Studio you are always logged in as TestUser, so that’s the User we link to our first School Employee.&lt;/p&gt;

&lt;h1&gt;Validation On The Server&lt;/h1&gt;

&lt;p&gt;Now we have an employee and books to count.  So where do we start the validation process? I think the best place to start is at the bottom; i.e. don’t allow invalid changes to the database. Validating the entity is the closest we can get to the storage level working within LightSwitch. if we go back to our list of requirements we find that the first one is to prevent an employee of one school from updating the counts for a different school. &lt;/p&gt;

&lt;p&gt;We add the code to enforce this rule to the SchoolBooks_Validate event. If your Entity window is wide enough you’ll see a ‘Write Code’ tab. Click on the down arrow icon to the right and select SchoolBooks_Validate, which as you can see, is called when an item is validated on the server:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_24.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_thumb_11.png" width="644" height="357" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If the window is not wide enough you can still get to the dropdown as shown below:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_26.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_thumb_12.png" width="644" height="442" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And here’s the code:&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;namespace&lt;/span&gt; LightSwitchApplication
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; partial &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; ApplicationDataService
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        partial &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; SchoolBooks_Validate(SchoolBook entity, EntitySetValidationResultsBuilder results)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            var LoggedInSchoolEmployee = (from emp &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; DataWorkspace.ApplicationData.SchoolEmployees
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                                          where emp.User == Application.Current.User.Name
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                                          select emp).FirstOrDefault();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (LoggedInSchoolEmployee == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                results.AddEntityError("&lt;span style="color: #8b0000"&gt;Denied&lt;/span&gt;");
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt;;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (entity.School.Id != LoggedInSchoolEmployee.School.Id)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                results.AddEntityError(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Format("&lt;span style="color: #8b0000"&gt;Employee {0} belongs to {1}, book belongs to {2}&lt;/span&gt;",
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                                                        LoggedInSchoolEmployee.Name,
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                                                        LoggedInSchoolEmployee.School.Name,
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                                                        entity.School.Name));
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;The error message when the logged-in user is not an employee has almost no information, The message when the user is an employee of a different school goes to the other extreme. You can also write it like this if you don’t need the Employee’s information.&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;partial &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; SchoolBooks_Validate(SchoolBook entity, EntitySetValidationResultsBuilder results)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;int&lt;/span&gt;? LoggedInSchoolEmployeeSchoolId = (from emp &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; DataWorkspace.ApplicationData.SchoolEmployees
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                                    where emp.User == Application.Current.User.Name
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                                    select emp).FirstOrDefault().School.Id;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (LoggedInSchoolEmployeeSchoolId.HasValue == &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        results.AddEntityError("&lt;span style="color: #8b0000"&gt;Denied&lt;/span&gt;");
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt;;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (entity.School.Id != LoggedInSchoolEmployeeSchoolId)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        results.AddEntityError(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Format("&lt;span style="color: #8b0000"&gt;Employee {0} belongs to {1}, book belongs to {2}&lt;/span&gt;",
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                                                "&lt;span style="color: #8b0000"&gt;Unknown&lt;/span&gt;", "&lt;span style="color: #8b0000"&gt;Unknown&lt;/span&gt;",
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                                                entity.School.Name));
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt;;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Let’s test. To start with I changed the SchoolEmployee User to ‘TestUser2’ to test the case where the logged-in User is not a SchoolEmployee. Here’s what I  get after trying to change a count and clicking ‘Save’:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_28.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_thumb_13.png" width="644" height="262" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If I change Gabe's User back to ‘TestUser’ and click ‘Save’ again I get this message:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_30.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_thumb_14.png" width="644" height="212" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;Validation On The Client&lt;/h1&gt;

&lt;p&gt;So far so good. Now let’s handle our second requirement, which is to prevent invalid counts. We start by preventing negative numbers:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_67.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_thumb_31.png" width="639" height="484" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To make it a little more interesting I added the admittedly contrived requirement that the sum of Count New, Count Used Good, and Count Used Poor must equal Count Total. We handle this by adding Validation to the SchoolBook CountTotal property:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_31.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_thumb_2.png" width="644" height="335" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice that where the SchoolBooks_Validate method is a member of ApplicationDataService, and runs on the server, CountTotal_Validate is a member of the SchoolBook class and runs on the client (but, as it turns out, not &lt;em&gt;just&lt;/em&gt; on the client).&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;namespace&lt;/span&gt; LightSwitchApplication
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; partial &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; SchoolBook
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        ...
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        partial &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; CountTotal_Validate(EntityValidationResultsBuilder results)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (CountUsedGood + CountUsedPoor + CountNew != CountTotal)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                results.AddPropertyError("&lt;span style="color: #8b0000"&gt;Individual counts must add up to count total&lt;/span&gt;");
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;So instead of seeing a message after clicking Save, one appears immediately when the input changes:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_33.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_thumb_15.png" width="644" height="471" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;More Validation On The Server, No Extra Charge&lt;/h1&gt;

&lt;p&gt;Entity property validation also runs on the server, so that’s all the code you have to write. To prove this, I added a button to deliberately add a SchoolBook with invalid count total.&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;namespace&lt;/span&gt; LightSwitchApplication
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; partial &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; DebugBooks
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        partial &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; CreateInvalidSchoolBook_Execute()
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            var newSchoolBook = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.DataWorkspace.ApplicationData.SchoolBooks.AddNew();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            newSchoolBook.CountTotal = 50;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            newSchoolBook.CountUsedGood = 60;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            newSchoolBook.School = (from school &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.DataWorkspace.ApplicationData.Schools
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                                    select school).FirstOrDefault();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            newSchoolBook.Book = (from book &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.DataWorkspace.ApplicationData.Books
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                                  select book).FirstOrDefault();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.DataWorkspace.ApplicationData.SaveChanges();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;And here’s the result, complete with custom error message provided by CountTotal_Validate:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_37.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_thumb_17.png" width="1028" height="280" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So we were able to satisfy two of our requirements in one piece of code. We prevented invalid counts from making it to the database and we validated the counts at the screen level at the time of entry. &lt;/p&gt;

&lt;h1&gt;Filtering on Logged-In User&lt;/h1&gt;

&lt;p&gt;Now we move on to filtering on User, because the last requirement is to prevent an employee from seeing counts from a different school. There are a couple of ways to go about it. The first is to add a query to the SchoolBooks table.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_39.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_thumb_18.png" width="534" height="484" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We name the query LoggedInEmployeeSchoolBooks and handle the filtering in the preprocess query by looking up the Logged-In Employee and then passing only SchoolBooks  belonging to the same school.&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;partial &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; LoggedInEmployeeSchoolBooks_PreprocessQuery(&lt;span style="color: #0000ff"&gt;ref&lt;/span&gt; IQueryable&lt;SchoolBook&gt; query)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    var LoggedInEmployee = (from entity &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; DataWorkspace.ApplicationData.SchoolEmployees
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                                    where entity.User == Application.Current.User.Name
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                                    select entity).FirstOrDefault();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    query = LoggedInEmployee != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; ?
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        from entity &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; query
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        where entity.School.Id == LoggedInEmployee.School.Id
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        select entity : &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;And add a screen based on the new query:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_41.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_thumb_19.png" width="611" height="484" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If we put Gabe at Tom Landry Middle School:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_43.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_thumb_20.png" width="644" height="359" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;He only sees books from Tom Landry:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_45.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_thumb_21.png" width="644" height="345" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;Universal Filtering&lt;/h1&gt;

&lt;p&gt;Now let’s say you had an application where prevention of unauthorized data access is critical and/or there are a lot of screens to maintain. The pre-process query works fine, but you have to remember to use it as the basis for every screen and every dropdown that presents data that should be filtered on the user. It would be nice if every screen automatically filtered SchoolBook on logged-in Employee. This can be easily done by editing the SchoolBooks_All_PreprocessQuery .&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_47.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_thumb_22.png" width="644" height="454" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you would expect, it’s the same query:&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;partial &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; SchoolBooks_All_PreprocessQuery(&lt;span style="color: #0000ff"&gt;ref&lt;/span&gt; IQueryable&lt;SchoolBook&gt; query)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    var LoggedInEmployee = (from entity &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; DataWorkspace.ApplicationData.SchoolEmployees
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                            where entity.User == Application.Current.User.Name
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                            select entity).FirstOrDefault();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    query = LoggedInEmployee != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; ?
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        from entity &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; query
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        where entity.School.Id == LoggedInEmployee.School.Id
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        select entity : &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Now when we run the app we see that the unfiltered screen is now filtered.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_49.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_thumb_23.png" width="644" height="425" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;Opening Holes In The Filter&lt;/h1&gt;

&lt;p&gt;It’s nice to be able to know all screens will filter on logged-in user without having to take any steps to do so. But you might have to make exceptions. Below I add a DistrictAccess  Permission which we can use for that purpose:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_51.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_thumb_24.png" width="644" height="388" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;partial &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; SchoolBooks_All_PreprocessQuery(&lt;span style="color: #0000ff"&gt;ref&lt;/span&gt; IQueryable&lt;SchoolBook&gt; query)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (Application.Current.User.HasPermission(Permissions.DistrictAccess))
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt;;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    var LoggedInEmployee = (from entity &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; DataWorkspace.ApplicationData.SchoolEmployees
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                            where entity.User == Application.Current.User.Name
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                            select entity).FirstOrDefault();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    query = LoggedInEmployee != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; ?
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        from entity &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; query
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        where entity.School.Id == LoggedInEmployee.School.Id
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        select entity : &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Now when logged in as TestUser, who has DistrictAccess Permission, we see all SchoolBooks.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_53.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_thumb_25.png" width="514" height="484" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This way we apply the tightest possible security and then add exceptions as opposed to remembering to add security screen by screen, which might be an overstatement, because all you have to do is to remember to base the screen off the proper query, but still. Of course we can still screw it up, but it takes more effort. Or maybe not. Now we have to be careful about the permissions of the screen user if the relationships don’t fit into the tidy little scenario shown here. &lt;/p&gt;

&lt;p&gt;Another alternative is to leave in the most restrictive filtering so that all screens that access that DataSource will filter on logged-in user with no exceptions. Then, to make exceptions, create a separate DataSource based on a WCF RIA Service that accesses the same table. You can apply different filtering, or no filtering at all, as required by the screens you will add that access that DataSource. Which puts you back to the position of making sure each screen accesses the correct DataSource No matter what, you have to be careful, but you do have options on how to divide up the responsibility.&lt;/p&gt;

&lt;p&gt;Of course DistrictAccess doesn’t allow update of counts where the user is not an employee of the same school:&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_35.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/78/Windows-Live-Writer-0d9f0986ea4c_1031F-image_thumb_16.png" width="644" height="159" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you wanted DistrictAccess to allow counts to be updated just exit immediately as we did in the pre-process query by adding this as the first statement in SchoolBooks_Validate();&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (Application.User.HasPermission(Permissions.DistrictAccess))
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt;;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Testing can get a bit tedious as you add more permissions because you can only ever log in as TestUser unless you publish the application and run it outside of Visual Studio.&lt;/p&gt;

&lt;p&gt;Of course in a real-world app there would probably be only one employee table containing both school and district employees and there would be some sort of audit on the counts against employee, but that’s outside the illustrational scope of this example.&lt;/p&gt;

&lt;p&gt;So that’s a glimpse into validation and filtering at different levels mostly based on the logged-in user belonging to the same group as the data.&lt;/p&gt;

&lt;p&gt;I encourage you again to &lt;a href="http://blogs.msdn.com/b/lightswitch/archive/2010/08/30/overview-of-data-validation-in-lightswitch-applications-prem-ramanathan.aspx" target="_blank"&gt;see this post&lt;/a&gt; by Prem Ramanathan and this &lt;a href="http://www.code-magazine.com/articleprint.aspx?quickid=1105091&amp;printmode=true" target="_blank"&gt;article he wrote for Code magazine&lt;/a&gt;. And to find out more about the Save Pipeline &lt;a href="http://www.code-magazine.com/Article.aspx?quickid=1103071" target="_blank"&gt;check out this article by Dan Seefeldt&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;The LightSwitch project is available &lt;a title="http://RichardWaddell.ADefWebserver.com/LevelsOfValidation.zip" href="http://RichardWaddell.ADefWebserver.com/LevelsOfValidation.zip"&gt;here.&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;a href=http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/78/Levels-of-Validation-and-Filtering-on-User-Membership.aspx&gt;More ...&lt;/a&gt;</description>
      <author>webmaster@adefwebserver.com</author>
      <comments>http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/78/Levels-of-Validation-and-Filtering-on-User-Membership.aspx#Comments</comments>
      <slash:comments>0</slash:comments>
      <guid isPermaLink="true">http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/78/Levels-of-Validation-and-Filtering-on-User-Membership.aspx</guid>
      <pubDate>Sat, 03 Dec 2011 16:22:09 GMT</pubDate>
      <trackback:ping>http://lightswitchhelpwebsite.comDesktopModules/BlogTrackback.aspx?id=78</trackback:ping>
    </item>
    <item>
      <title>LightSwitch&amp;ndash;Modal Add and Edit Windows</title>
      <link>http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/33/LightSwitch-ndash-Modal-Add-and-Edit-Windows.aspx</link>
      <description>&lt;p&gt;The default Add and Edit screens generated by LightSwitch often don’t allow the control you need to meet the business requirements.  Consider the scenario where an entity must have a password column.  Ideally we’d want the ‘Add’ screen to look something like this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_6.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_thumb_2.png" width="644" height="226" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The default Add and Edit screens are inadequate for two reasons.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;No masked password text box &lt;/li&gt;    &lt;li&gt;A second password text box is required for matching, requiring a property that doesn’t map to the entity. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Fortunately, it’s easy to supply your own custom Add and Edit screens, and often a single screen can serve as both. Unfortunately there’s no way to display the screen modally, so when the user clicks the 'Add’ button they are taken to a new tabbed screen. On completion control returns to the original screen, but it’s not the ideal user experience.&lt;/p&gt;  &lt;p&gt;Fortunately it’s possible to supply a modal window, unfortunately it takes a little more work than just creating a screen, but not as much as you might think. Thanks to &lt;a href="http://lightswitchhelpwebsite.com/Forum/tabid/63/aft/74/Default.aspx" target="_blank"&gt;Michael Washington&lt;/a&gt; for the &lt;a href="http://lightswitchhelpwebsite.com/Forum/tabid/63/aft/72/Default.aspx" target="_blank"&gt;Modal Window stuff&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;I’m going to take you through the steps required to create the modal window you see above for adding an entity and one for editing. I wouldn’t be surprised if you could use one window for both, but let’s keep it simple for now.&lt;/p&gt;  &lt;h2&gt;Create The Subscriber Entity and Screen &lt;/h2&gt;  &lt;p&gt;First, create a Subscriber entity with UserName and Password properties:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_10.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_thumb_4.png" width="644" height="197" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Create an Editable Grid Screen:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_12.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_thumb_5.png" width="644" height="456" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h2&gt;Add A Modal Window Group&lt;/h2&gt;  &lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_14.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_thumb_6.png" width="425" height="484" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;A Rows Layout Group is created by default; change it to a Modal Window:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_16.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_thumb_7.png" width="244" height="211" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Drag the UserName and Password properties under the Modal Window:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_18.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_thumb_8.png" width="644" height="384" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Change the name to AddSubscriber and uncheck the ‘Is Visible’ checkbox.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_20.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_thumb_9.png" width="644" height="455" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h2&gt;Add a ReEntered Password Property and Bind to the ReEntered Password TextBox&lt;/h2&gt;  &lt;p&gt;Click on ‘Add Data Item…’ and add a ReEnteredNewPassword string property that is not required:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_22.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_thumb_10.png" width="414" height="484" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Drag the ReEnteredNewPassword property to the Modal Window:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_24.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_thumb_11.png" width="644" height="245" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;We need a Subscriber for the add screen to use, so add a NewSubscriber property:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_28.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_thumb_13.png" width="437" height="484" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h2&gt;Override the Add Button Execute Code&lt;/h2&gt;  &lt;p&gt;Before we get into binding or custom controls, let’s hook up the Add Button:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_26.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_thumb_12.png" width="644" height="377" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;partial &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; gridAddAndEditNew_Execute()
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.OpenModalWindow("&lt;span style="color: #8b0000"&gt;AddSubscriber&lt;/span&gt;");
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Resulting in:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_32.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_thumb_3.png" width="644" height="206" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We’re on the right track. As you probably already suspect, the User Name and Password boxes are grayed-out because the NewSubscriber property is null; we have a property, but no one is home. So we’ll new up the property and initialize the ReEnteredNewPassword property at the same time: &lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;partial&lt;/span&gt; void gridAddAndEditNew_Execute()
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    NewSubscriber = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Subscriber();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    ReEnteredNewPassword = &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;.Empty;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    this.OpenModalWindow(ADD_SUBSCRIBER_WINDOW);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    this.FindControl(ADD_SUBSCRIBER_WINDOW).ControlAvailable += 
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; EventHandler&lt;ControlAvailableEventArgs&gt;(NewSubscriber_WindowAvailable);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;
Actually, we’re a little ahead of ourselves, but this allows me to point out the value of constants when dealing with Modal Window group names. You’ll be using each one more than twice, as a matter of fact, so it makes sense to create a constant, especially with all this new-fangled binding. Why in my day if it compiled you knew it was good to go. &lt;img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-punch" alt="Punch" src="/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-wlEmoticon-punch_2.png" /&gt; 

&lt;p&gt;With just that much code we have a workable Add Subscriber window. As you can dimly see below, the values entered in the New Subscriber window show up in the Subscriber list – our NewSubscriber becomes part of the DataWorkspace Subscriber collection and so is bound to the list just like all the other Subscribers; now it can be saved or deleted just as though we had added it directly to the list.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_3.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_thumb.png" width="644" height="319" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;&lt;/h2&gt;

&lt;h2&gt;&lt;/h2&gt;

&lt;h2&gt;Formatting&lt;/h2&gt;

&lt;p&gt;Before moving on, let’s clean up the UI a little bit. This is one of the things that’s so cool about LightSwitch. All you have to do to align the columns is add a Rows Layout group. The trickiest part is clicking the right place with the right button.&lt;/p&gt;

&lt;p&gt;Right-click on the little down arrow between ‘Modal Window’ and ‘Add Subscriber’ then click on Add Group:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_34.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_thumb_14.png" width="644" height="199" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Resulting in:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_36.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_thumb_15.png" width="644" height="304" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now drag the three controls to the Rows Layout Group and change ReEnteredNewPassword Display Name to ReEnter:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_40.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_thumb_17.png" width="644" height="321" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Who’s got a mouse and doesn’t need StackPanels or Grids? This nerd!!!!&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_42.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_thumb_18.png" width="644" height="196" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Converting to Custom Controls&lt;/h2&gt;

&lt;p&gt;Ok, on to the PasswordBox Custom Controls. Left-click on the down-arrow between the label icon and ‘Password’ and select Custom Control:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_44.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_thumb_19.png" width="244" height="206" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Change the Password Custom Control Custom Control (?) property:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_46.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_thumb_20.png" width="644" height="366" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select System.Windows.Controls.PasswordBox:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_48.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_thumb_21.png" width="329" height="484" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Do the same for ReEnteredNewPassword.&lt;/p&gt;

&lt;p&gt;If you run this now, you’ll find that the Password boxes are masked, but the binding no longer works; text entered in the Password boxes does not show up in the new row in the list of Subscribers.&lt;/p&gt;

&lt;h2&gt;Binding the PasswordBox Controls&lt;/h2&gt;

&lt;p&gt;In the code below I’ve set the binding for all four password boxes, two for Add and two for Edit. Thanks to &lt;a href="http://dotnettim.wordpress.com/2011/04/14/lightswitch-creating-a-masked-password-textbox-control/" target="_blank"&gt;Tim Leung&lt;/a&gt; for the whole masked password and binding thing. &lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;const&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; EDIT_SUBSCRIBER_WINDOW = "&lt;span style="color: #8b0000"&gt;EditSubscriber&lt;/span&gt;";
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;const&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; ADD_SUBSCRIBER_WINDOW = "&lt;span style="color: #8b0000"&gt;AddSubscriber&lt;/span&gt;";
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;const&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; EDIT_PASSWORD_CONTROL = "&lt;span style="color: #8b0000"&gt;EditScreenPassword&lt;/span&gt;";
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;const&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; EDIT_PASSWORD_REENTER_CONTROL = "&lt;span style="color: #8b0000"&gt;EditScreenReEnterPassword&lt;/span&gt;";
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;const&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; NEW_PASSWORD_CONTROL = "&lt;span style="color: #8b0000"&gt;AddScreenPassword&lt;/span&gt;";
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;const&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; NEW_PASSWORD_REENTER_CONTROL = "&lt;span style="color: #8b0000"&gt;AddScreenReEnterPassword&lt;/span&gt;";
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;const&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; PASSWORD_MATCH_ERROR_TEMPLATE = "&lt;span style="color: #8b0000"&gt;Reentered Password does not match Password in {0}&lt;/span&gt;";
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;partial &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; EditableSubscribersGrid_Created()
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #008000"&gt;// Bind the four Password properties to the PassWordBox Screen CustomControls&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #008000"&gt;// Edit Password Box&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    IContentItemProxy proxyEditPassword = 
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.FindControl(EDIT_PASSWORD_CONTROL);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #008000"&gt;// WE are binding to the PasswordProperty dependency property of the PassWordBox, &lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    proxyEditPassword.SetBinding
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        (System.Windows.Controls.PasswordBox.PasswordProperty, 
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        "&lt;span style="color: #8b0000"&gt;Value&lt;/span&gt;", System.Windows.Data.BindingMode.TwoWay);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #008000"&gt;// Edit ReEnter Password Box&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    IContentItemProxy proxyReEnteredEditPassword = 
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.FindControl( EDIT_PASSWORD_REENTER_CONTROL);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    proxyReEnteredEditPassword.SetBinding
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        (System.Windows.Controls.PasswordBox.PasswordProperty, 
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        "&lt;span style="color: #8b0000"&gt;Value&lt;/span&gt;", System.Windows.Data.BindingMode.TwoWay);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #008000"&gt;// New Passowrd Box&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    IContentItemProxy proxyNewPassword = 
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.FindControl(NEW_PASSWORD_CONTROL);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    proxyNewPassword.SetBinding
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        (System.Windows.Controls.PasswordBox.PasswordProperty, 
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        "&lt;span style="color: #8b0000"&gt;Value&lt;/span&gt;", System.Windows.Data.BindingMode.TwoWay);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #008000"&gt;// New ReEnter Password Box&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    IContentItemProxy proxyReEnteredNewPassword = 
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.FindControl(NEW_PASSWORD_REENTER_CONTROL);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    proxyReEnteredNewPassword.SetBinding
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        (System.Windows.Controls.PasswordBox.PasswordProperty, 
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        "&lt;span style="color: #8b0000"&gt;Value&lt;/span&gt;", System.Windows.Data.BindingMode.TwoWay);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;h2&gt;Formatting At Run Time&lt;/h2&gt;

&lt;p&gt;If you run the application now you’ll find that you can successfully  add new Subscribers. But the UI needs a little work. Let’s do that at run time so we can experiment without having to re-build the application. To enable this capability, run the application in debug mode by hitting F5. After you click the Add button you’ll see:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_30.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_thumb_1.png" width="644" height="198" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The issue is that the Password boxes are unsightly. We can get into design mode by clicking on the ‘Design Screen’ icon on the upper-right corner of the page:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_50.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_thumb_22.png" width="128" height="124" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You’ll see something like this.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_56.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_thumb_25.png" width="644" height="391" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With some re-sizing and scrolling we can focus on the Sizing properties. Let’s set Horizontal Alignment to Stretch for both Password and ReEnter:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_54.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_thumb_24.png" width="577" height="484" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on Save and then the Add Button:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_58.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_thumb_26.png" width="644" height="196" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Maybe you’d like to size the textboxes to more closely match the likely input. Click on Design Screen, change the Horizontal Alignment back to Left, and set MinWidth to whatever you prefer, I chose 150:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_60.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_thumb_27.png" width="644" height="197" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Why, you ask, are the User Name and Password captions bold and ReEnter is not? I have not a clue. The captions are set through the Custom Control Display Name, but I don’t see any setting to affect the font weight. Doesn’t mean it can’t be changed, but I don’t know how to do it.&lt;/p&gt;

&lt;h2&gt;Validate the Password&lt;/h2&gt;

&lt;p&gt;Ok, now let’s add some validation, which consists of requiring that the values entered into the Password and ReEnter textboxes match. We already have our ReEnteredNewPassword property and it’s bound to the ReEnter Custom Control so we can go directly to validation&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_62.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_thumb_28.png" width="644" height="388" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And here’s the code:&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;partial &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; ReEnteredNewPassword_Validate(ScreenValidationResultsBuilder results)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.NewSubscriber != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; &amp;&amp; 
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.NewSubscriber.Password != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; &amp;&amp; 
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        ReEnteredNewPassword != &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.NewSubscriber.Password)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        results.AddPropertyError
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            (String.Format(PASSWORD_MATCH_ERROR_TEMPLATE, "&lt;span style="color: #8b0000"&gt;New Subscriber&lt;/span&gt;"));
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Pretty straightforward. Now if the entered password values don’t match:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_64.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_thumb_29.png" width="644" height="303" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The validation issue will appear as soon as you tab away from Password and remain until you enter a matching value in Re-Enter, which is a bit naggy, but kind of unavoidable given the nature of binding.&lt;/p&gt;

&lt;h2&gt;Add and Cancel Buttons&lt;/h2&gt;

&lt;p&gt;This is serviceable, but a bit clumsy in that you can only cancel an add by deleting it from the Subscriber list after you exit the Add Subscriber window. We need Add and Cancel buttons. Right-click where indicated below and select Add Button:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_66.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_thumb_30.png" width="644" height="324" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Name it SubmitAdd:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_72.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_thumb_33.png" width="644" height="335" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Change the Display Name to ‘Add’. Right-click where indicated below and select ‘Edit Execute Code’:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_70.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_thumb_32.png" width="644" height="360" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It turns out all we have to do is close the window. As you saw above, the new Subscriber becomes part of the collection on creation, and remains so unless deleted.&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;partial&lt;/span&gt; void SubmitAdd_Execute()
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    CloseAddSubscriberWindow();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; void CloseAddSubscriberWindow()
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    this.CloseModalWindow(ADD_SUBSCRIBER_WINDOW);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    this.FindControl(ADD_SUBSCRIBER_WINDOW).IsVisible = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Notice that although OpenModalWindow sets the control IsVisible property to true, CloseModalWindow does not set it to false. If you don’t set it yourself you see this at the bottom of the page:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_74.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_thumb_34.png" width="644" height="158" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Add the Cancel button and the following CanExecute code:
  &lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;partial&lt;/span&gt; void CancelAdd_Execute()
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    CancelAddSubscriberChanges();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    CloseAddSubscriberWindow();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; void CancelAddSubscriberChanges()
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    foreach (Subscriber subscriber &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; this.DataWorkspace.ApplicationData.Details.
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                                GetChanges().AddedEntities.OfType&lt;Subscriber&gt;())
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        subscriber.Details.DiscardChanges();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;
&lt;/p&gt;

&lt;h2&gt;Subscribing to the Modal Window Close Event&lt;/h2&gt;

&lt;p&gt;That covers the buttons, but what if the user clicks on the little ‘x’ in the upper-right corner. That should be the same as cancel, but as we’ve seen it’s not. We intercept that event by subscribing to the Modal Window close event. That requires a little setup. You saw a preview back when I showed you the Add button event handler:&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;partial&lt;/span&gt; void gridAddAndEditNew_Execute()
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    NewSubscriber = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Subscriber();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    ReEnteredNewPassword = &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;.Empty;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    this.OpenModalWindow(ADD_SUBSCRIBER_WINDOW);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    this.FindControl(ADD_SUBSCRIBER_WINDOW).ControlAvailable += 
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; EventHandler&lt;ControlAvailableEventArgs&gt;(NewSubscriber_WindowAvailable);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;So I’ll transition now to the event handler for the Edit button so we can cover the Edit Modal Window and the close event handling at the same time. The only difference in initialization is that we now have an existing Subscriber to work with.&lt;/p&gt;

&lt;p&gt;As to the close event, we don’t have access to the underlying control until the ControlAvailable event, so that’s where we subscribe to the closed event. The nullable ChildWindow.DialogResult property will be null if the window was closed with the ‘x’, so the changes are canceled.
  &lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;partial &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; gridEditSelected_Execute()
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #008000"&gt;// The Edit Button has been selected&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    ReEnteredEditPassword = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Subscribers.SelectedItem.Password;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.OpenModalWindow(EDIT_SUBSCRIBER_WINDOW);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #008000"&gt;// We need to add a Closed event handler to the underlying control which we have access to when we catch the ControlAvailable event&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.FindControl(EDIT_SUBSCRIBER_WINDOW).ControlAvailable += &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; EventHandler&lt;ControlAvailableEventArgs&gt;(EditSubscriber_WindowAvailable);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;void&lt;/span&gt; EditSubscriber_WindowAvailable(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, ControlAvailableEventArgs e)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.FindControl(EDIT_SUBSCRIBER_WINDOW).ControlAvailable -= &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; EventHandler&lt;ControlAvailableEventArgs&gt;(EditSubscriber_WindowAvailable);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    ((ChildWindow)e.Control).Closed += &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; EventHandler(EditSubscriber_Closed);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;void&lt;/span&gt; EditSubscriber_Closed(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, EventArgs e)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    ((ChildWindow)sender).Closed -= &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; EventHandler(EditSubscriber_Closed);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (!((ChildWindow)sender).DialogResult.HasValue)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        CancelEditSubscriberChanges();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    CloseEditSubscriberWindow();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;
&lt;/p&gt;

&lt;p&gt;The validation could use some fine-tuning in that in the ‘Add Subscriber’ window you can ignore the mismatched password warning and click the Add button, which should be disabled. Then you’re stuck with a validation error you can only clear by clicking ‘Refresh’. Same problem if you click the ‘x’ or Cancel button with a mismatched password error showing.  &lt;/p&gt;

&lt;p&gt;The Add button is pretty easy to handle.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_76.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_thumb_35.png" width="644" height="358" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;partial &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; SubmitAdd_CanExecute(&lt;span style="color: #0000ff"&gt;ref&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; result)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    result = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.NewSubscriber != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; &amp;&amp;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.NewSubscriber.Password != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; &amp;&amp;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        ReEnteredNewPassword == &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.NewSubscriber.Password;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_78.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/33/Windows-Live-Writer-LightSwitchModal-Add-and-Edit-Windows_7141-image_thumb_36.png" width="569" height="257" /&gt;&lt;/a&gt;

  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:511a9444-b430-4b28-b751-44a69b2af41f" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/LightSwitch" rel="tag"&gt;LightSwitch&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Modal+Windows" rel="tag"&gt;Modal Windows&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Custom+Controls" rel="tag"&gt;Custom Controls&lt;/a&gt;,&lt;a href="http://technorati.com/tags/PasswordBox" rel="tag"&gt;PasswordBox&lt;/a&gt;&lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;The ‘x’ and Cancel Button situations where the passwords are mismatched can be handled by setting NewSubscriber to null. This causes the validation code to ignore the mismatch:&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; void CancelAddSubscriberChanges()
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    foreach (Subscriber subscriber &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; this.DataWorkspace.ApplicationData.Details.
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                                GetChanges().AddedEntities.OfType&lt;Subscriber&gt;())
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        subscriber.Details.DiscardChanges();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    NewSubscriber = null;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;And Robert is your Father’s brother!!!&lt;/p&gt;



&lt;p&gt;The LightSwitch project is available at &lt;a title="http://lightswitchhelpwebsite.comhttp://lightswitchhelpwebsite.com/Downloads.aspx" href="http://lightswitchhelpwebsite.com/Downloads.aspx"&gt;http://lightswitchhelpwebsite.comhttp://lightswitchhelpwebsite.com/Downloads.aspx&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;a href=http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/33/LightSwitch-ndash-Modal-Add-and-Edit-Windows.aspx&gt;More ...&lt;/a&gt;</description>
      <author>webmaster@adefwebserver.com</author>
      <comments>http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/33/LightSwitch-ndash-Modal-Add-and-Edit-Windows.aspx#Comments</comments>
      <slash:comments>28</slash:comments>
      <guid isPermaLink="true">http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/33/LightSwitch-ndash-Modal-Add-and-Edit-Windows.aspx</guid>
      <pubDate>Tue, 14 Jun 2011 18:17:17 GMT</pubDate>
      <trackback:ping>http://lightswitchhelpwebsite.comDesktopModules/BlogTrackback.aspx?id=33</trackback:ping>
    </item>
    <item>
      <title>Drag and Drop and Events in LightSwitch Custom Controls</title>
      <link>http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/27/Drag-and-Drop-and-Events-in-LightSwitch-Custom-Controls.aspx</link>
      <description>&lt;p&gt; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/27/Windows-Live-Writer-adfb2cc2651b_10FE8-image_17.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/27/Windows-Live-Writer-adfb2cc2651b_10FE8-image_thumb_7.png" width="227" height="189" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;LightSwitch removes so much tedium from programming that I’m hoping it can be integrated into any Silverlight application. Obviously that requires Custom Controls, so the focus becomes finding the best patterns for interaction between LightSwitch and Custom Controls.&lt;/p&gt;  &lt;p&gt;My first goal was to incorporate drag and drop. I spent a lot of time trying to come up with scenarios that were not trivial but also wouldn’t take a long time to set up. But I kept running into a fuzzy area when I tried to think about the nature of the relationship between LightSwitch and the Custom Control. I was actually happy when I realized this because it meant I could start at the most basic level and work up. In other words, no hard thinking for awhile.&lt;/p&gt;  &lt;p&gt;So, compulsive (or is it obsessive) that I am, even though Custom Controls are not totally new to me, I began by creating a New Data Screen linked to no table. To the screen I added a string property named BasicMessage and dragged it onto the screen layout, resulting in a TextBox bound to the BasicMessage property.  To supply the Custom Control I added a SilverLight Class Library project named CustomControls to the solution and to that project added a UserControl fumble-fingeredly named DragaArena consisting of a Beige 150 x 150 pixel Canvas. &lt;/p&gt;  &lt;p&gt;To add DragaArena to the screen, I added a Custom Control under the BasicMessage TextBox. I changed the TextBox Display name to LightSwitch and the Custom Control Display Name to SilverLight.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/27/Windows-Live-Writer-adfb2cc2651b_10FE8-image_4.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/27/Windows-Live-Writer-adfb2cc2651b_10FE8-image_thumb_1.png" width="644" height="366" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;To bind the Custom Control to DragaArena, click on Choices on the Custom Control properties panel. Note the name of the CustomControl is ‘DragArena’. This is important because CreateNew codebehind will be searching for this control in order to subscribe to the BallDropped event. I should have made it more distinguishable from the name of the SilverLight UserControl it encapsulates, ‘DragaArena’, but forewarned is forearmed.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/27/Windows-Live-Writer-adfb2cc2651b_10FE8-image_6.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/27/Windows-Live-Writer-adfb2cc2651b_10FE8-image_thumb_2.png" width="644" height="246" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;(1) Click on Add Reference (2) Select CustomControls and click OK (3) Select DragaArena and click OK&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/27/Windows-Live-Writer-adfb2cc2651b_10FE8-image_8.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/27/Windows-Live-Writer-adfb2cc2651b_10FE8-image_thumb_3.png" width="590" height="484" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Now we add a Label and a TextBox to DragaArena and bind them to BasicMessage. There’s also a ball we’re going to use for dragging and dropping:&lt;/p&gt;  &lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;&lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;UserControl&lt;/span&gt; &lt;span style="color: #ff0000"&gt;x&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;Class&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"CustomControls.DragaArena"&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/winfx/2006/xaml/presentation"&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;x&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/winfx/2006/xaml"&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;d&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/expression/blend/2008"&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;mc&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.openxmlformats.org/markup-compatibility/2006"&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #ff0000"&gt;mc&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;Ignorable&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"d"&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #ff0000"&gt;d&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;DesignHeight&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"300"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;d&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;DesignWidth&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"400"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;sdk&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;&lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt; &lt;span style="color: #ff0000"&gt;x&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"LayoutRoot"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Background&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"#FFFFE6CD"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"150"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"150"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;		&lt;span style="color: #0000ff"&gt;&lt;&lt;/span&gt;&lt;span style="color: #c71585"&gt;sdk&lt;/span&gt;:&lt;span style="color: #800000"&gt;Label&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"28"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;HorizontalAlignment&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Left"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;x&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"label1"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"120"&lt;/span&gt; 
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;			&lt;span style="color: #ff0000"&gt;Content&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"{Binding Screen.BasicMessage}"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"10"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"10"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;		&lt;span style="color: #0000ff"&gt;&lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;TextBox&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"23"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;HorizontalAlignment&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Left"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;x&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"textBox1"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Text&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"{Binding Screen.BasicMessage, Mode=TwoWay}"&lt;/span&gt; 
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;			&lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"120"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"10"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"30"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;		&lt;span style="color: #0000ff"&gt;&lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Ellipse&lt;/span&gt; &lt;span style="color: #ff0000"&gt;x&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"ball"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Fill&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"#FFF15F0A"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"38"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Stroke&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"Black"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"41"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;MouseLeftButtonDown&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"ball_MouseLeftButtonDown"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Left&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"34"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Canvas&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Top&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"79"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;	&lt;span style="color: #0000ff"&gt;&lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Canvas&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;&lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;UserControl&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Note the binding is to Screen.BasicMessage. At runtime the Content property of label1 and the Text property of textBox1 are bound to the BasicMessage property of the Screen object, which is the parent of DragaArena, in this case CreateNew.&lt;/p&gt;

&lt;p&gt;So now you can see the effect of the binding by entering some text:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/27/Windows-Live-Writer-adfb2cc2651b_10FE8-image_10.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/27/Windows-Live-Writer-adfb2cc2651b_10FE8-image_thumb_4.png" width="244" height="202" /&gt;&lt;/a&gt; &lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/27/Windows-Live-Writer-adfb2cc2651b_10FE8-image_12.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/27/Windows-Live-Writer-adfb2cc2651b_10FE8-image_thumb_5.png" width="229" height="189" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The drag and drop code is pretty straightforward considering I lifted 95% of it from Michael Washington. I feel unclean writing in the code-behind of a UserControl, but this is experimental code, and we’re all reasonable (hah – programmers) adults (hah – programmers) here so I’m sure the stigma won’t make me an outcast. Well, reasonably sure.&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;namespace&lt;/span&gt; CustomControls
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; partial &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; DragaArena : UserControl
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; Point _StartingDragPoint;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; DragaArena()
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            InitializeComponent();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;event&lt;/span&gt; EventHandler BallDropped;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;virtual&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; OnBallDropped(EventArgs e)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (BallDropped != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                BallDropped(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;, EventArgs.Empty);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; ball_MouseLeftButtonDown(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, System.Windows.Input.MouseButtonEventArgs e)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            FrameworkElement elem = sender &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; FrameworkElement;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            _StartingDragPoint = e.GetPosition(elem);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            elem.MouseMove += &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; MouseEventHandler(elem_MouseMove);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            elem.MouseLeftButtonUp += &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; MouseButtonEventHandler(elem_MouseLeftButtonUp);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            UpdateElementPosition(elem, e.GetPosition(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.LayoutRoot));
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; elem_MouseLeftButtonUp(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, MouseButtonEventArgs e)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            FrameworkElement elem = sender &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; FrameworkElement;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            elem.ReleaseMouseCapture();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            elem.MouseLeftButtonUp -= &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; MouseButtonEventHandler(elem_MouseLeftButtonUp);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            elem.MouseMove -= &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; MouseEventHandler(elem_MouseMove);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            OnBallDropped(EventArgs.Empty);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; elem_MouseMove(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, MouseEventArgs e)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            FrameworkElement elem = sender &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; FrameworkElement;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            Canvas canvas = elem.Parent &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; Canvas;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            UpdateElementPosition(elem, e.GetPosition(canvas));
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; UpdateElementPosition(FrameworkElement elem, Point newPoint)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            Canvas.SetLeft(elem, newPoint.X - _StartingDragPoint.X);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            Canvas.SetTop(elem, newPoint.Y - _StartingDragPoint.Y);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;You’ll need to add a reference to the CustomControls assembly. First select File View:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/27/Windows-Live-Writer-adfb2cc2651b_10FE8-image_19.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/27/Windows-Live-Writer-adfb2cc2651b_10FE8-image_thumb_8.png" width="589" height="484" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Add Reference:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/27/Windows-Live-Writer-adfb2cc2651b_10FE8-image_21.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/27/Windows-Live-Writer-adfb2cc2651b_10FE8-image_thumb_9.png" width="644" height="435" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select CustomControls:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/27/Windows-Live-Writer-adfb2cc2651b_10FE8-image_23.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/27/Windows-Live-Writer-adfb2cc2651b_10FE8-image_thumb_10.png" width="607" height="484" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Happily frustrating my expectations, subscribing to the event is easy peasy, considering I lifted it from &lt;a href="http://blogs.msdn.com/b/lightswitch/archive/2011/01/13/using-custom-controls-to-enhance-lightswitch-application-ui-part-1.aspx" target="_blank"&gt;Karol Zador-Przylecki&lt;/a&gt;. See the code at the very end of the article for the specific example. Here’s the code I wrote based on it. This is the point where we’re searching for the LightSwitch CustomControl, ‘DragArena’ from which we’re going to create a proxy from which we can access the encapsulated SilverLight User Control, ‘DragaArena’, in OnDragArenaControlAvailable:&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; CustomControls;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;namespace&lt;/span&gt; LightSwitchApplication
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; partial &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; CreateNew
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        IContentItemProxy _arenaProxy = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        partial &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; CreateNew_Created()
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            _arenaProxy = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.FindControl("&lt;span style="color: #8b0000"&gt;DragArena&lt;/span&gt;");
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            _arenaProxy.ControlAvailable += OnDragArenaControlAvailable;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            _arenaProxy.ControlUnavailable += OnDragArenaControlUnvailable;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; OnDragArenaControlAvailable(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, ControlAvailableEventArgs e)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            DragaArena arena = e.Control &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; DragaArena;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            arena.BallDropped += arena_BallDropped;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; OnDragArenaControlUnvailable(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, ControlUnavailableEventArgs e)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            DragaArena arena = e.Control &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; DragaArena;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            arena.BallDropped -= arena_BallDropped;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; arena_BallDropped(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, EventArgs e)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            BasicMessage = "&lt;span style="color: #8b0000"&gt;Ball Dropped&lt;/span&gt;";
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        partial &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; CreateNew_Closing(&lt;span style="color: #0000ff"&gt;ref&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; cancel)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            _arenaProxy.ControlAvailable -= OnDragArenaControlAvailable;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            _arenaProxy.ControlUnavailable -= OnDragArenaControlUnvailable;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;After dropping the ball:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/27/Windows-Live-Writer-adfb2cc2651b_10FE8-image_14.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="/Portals/0/Blog/Files/2/27/Windows-Live-Writer-adfb2cc2651b_10FE8-image_thumb_6.png" width="227" height="189" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So if you can handle everything through subscribing to events on the Custom Control you don’t need to give the Custom Control any knowledge of its parent other than the late binding in XAML. &lt;/p&gt;

&lt;p&gt;Stay tuned for an example where the dragged objects represent data from Screen and I totally rip off more code from Michael Washington.&lt;/p&gt;&lt;br /&gt;&lt;a href=http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/27/Drag-and-Drop-and-Events-in-LightSwitch-Custom-Controls.aspx&gt;More ...&lt;/a&gt;</description>
      <author>webmaster@adefwebserver.com</author>
      <comments>http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/27/Drag-and-Drop-and-Events-in-LightSwitch-Custom-Controls.aspx#Comments</comments>
      <slash:comments>4</slash:comments>
      <guid isPermaLink="true">http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/27/Drag-and-Drop-and-Events-in-LightSwitch-Custom-Controls.aspx</guid>
      <pubDate>Sat, 21 May 2011 16:29:00 GMT</pubDate>
      <trackback:ping>http://lightswitchhelpwebsite.comDesktopModules/BlogTrackback.aspx?id=27</trackback:ping>
    </item>
    <item>
      <title>LightSwitch: Creating a Relationship on current User through SecurityData.UserRegistrations Table</title>
      <link>http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/19/LightSwitch-Creating-a-Relationship-on-current-User-through-SecurityData-UserRegistrations-Table.aspx</link>
      <description>&lt;p&gt;Often we don’t care who the logged-in &lt;strong&gt;User&lt;/strong&gt; is because we can control what they can do through &lt;strong&gt;Roles&lt;/strong&gt; and &lt;strong&gt;Permissions. &lt;/strong&gt;But if the &lt;strong&gt;User&lt;/strong&gt; is a member of some group, it would be handy to place the &lt;strong&gt;Users&lt;/strong&gt; table in a many-to-one relationship with that group. In this example the groups are &lt;strong&gt;SalesTeams&lt;/strong&gt; made up of &lt;strong&gt;SalesPersons&lt;/strong&gt;. All &lt;strong&gt;Sales&lt;/strong&gt; made by a particular team are accessible only by members of that team. &lt;/p&gt;  &lt;p&gt;To make that happen a new &lt;strong&gt;User&lt;/strong&gt; is created, if necessary, when a &lt;strong&gt;SalesPerson&lt;/strong&gt; is created. Since a &lt;strong&gt;SalesPerson&lt;/strong&gt; is in a many-to-one relationship with &lt;strong&gt;SalesTeam&lt;/strong&gt;, so is the &lt;strong&gt;User. &lt;/strong&gt;This article shows you how to create the &lt;strong&gt;UserRegistration&lt;/strong&gt; and then two ways to identify the &lt;strong&gt;SalesPerson&lt;/strong&gt; associated with the logged-in &lt;strong&gt;User&lt;/strong&gt; and thereby the relationship with &lt;strong&gt;SalesTeam&lt;/strong&gt; and &lt;strong&gt;Sales&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;Start by adding a &lt;strong&gt;SalesTeam&lt;/strong&gt; entity:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_48.png"&gt;&lt;img style="background-image: none; border-bottom: 0px solid; border-left: 0px solid; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px solid; border-right: 0px solid; padding-top: 0px" title="image" alt="image" src="/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_thumb_6.png" width="620" height="144" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;A &lt;strong&gt;SalesTeam&lt;/strong&gt; is composed of &lt;strong&gt;SalesPersons&lt;/strong&gt;:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_6.png"&gt;&lt;img style="border-bottom: 0px solid; border-left: 0px solid; display: inline; border-top: 0px solid; border-right: 0px solid" title="image" alt="image" src="/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_thumb_2.png" width="608" height="484" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;We’re going to associate each &lt;strong&gt;SalesPerson&lt;/strong&gt; with a &lt;strong&gt;User&lt;/strong&gt;. Let’s make sure we’re agreed on what I mean by ‘&lt;strong&gt;User’&lt;/strong&gt;. Under &lt;strong&gt;Solution&lt;/strong&gt; &lt;strong&gt;Explorer&lt;/strong&gt; &lt;strong&gt;/&lt;/strong&gt; &lt;strong&gt;Properties / Access Control&lt;/strong&gt; select ‘&lt;strong&gt;User Forms authentication’&lt;/strong&gt; and check ‘&lt;strong&gt;Granted&lt;/strong&gt; &lt;strong&gt;for&lt;/strong&gt; &lt;strong&gt;debug’&lt;/strong&gt; next to &lt;strong&gt;SecurityAdministration&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_8.png"&gt;&lt;img style="border-bottom: 0px solid; border-left: 0px solid; display: inline; border-top: 0px solid; border-right: 0px solid" title="image" alt="image" src="/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_thumb_3.png" width="1028" height="327" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Press F5 to run the application, expand the &lt;strong&gt;Administration&lt;/strong&gt; menu, and click on ‘&lt;strong&gt;Users’&lt;/strong&gt;. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_10.png"&gt;&lt;img style="border-bottom: 0px solid; border-left: 0px solid; display: inline; border-top: 0px solid; border-right: 0px solid" title="image" alt="image" src="/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_thumb_4.png" width="644" height="482" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;As you can see, there are no &lt;strong&gt;Users&lt;/strong&gt; defined. In the lower-right corner we see that we are logged in as the special user &lt;strong&gt;TestUser&lt;/strong&gt; by virtue of running under &lt;strong&gt;Visual&lt;/strong&gt; &lt;strong&gt;Studio&lt;/strong&gt;. If this were a deployed application it would prompt for user and password on startup. Instead we are automatically logged-in for convenience during development.  The upshot is that in a deployed application the current &lt;strong&gt;User&lt;/strong&gt;, which can be determined through &lt;strong&gt;Application.Current.User.Name&lt;/strong&gt;, will always be one of the &lt;strong&gt;Users&lt;/strong&gt; you see on the &lt;strong&gt;Administration/Users&lt;/strong&gt; page shown above. Under &lt;strong&gt;Visual&lt;/strong&gt; &lt;strong&gt;Studio&lt;/strong&gt; it will always be &lt;strong&gt;TestUser&lt;/strong&gt;, which isn’t necessarily one of the &lt;strong&gt;Users&lt;/strong&gt; you see above.&lt;/p&gt;  &lt;p&gt;First of all, we need a property to bind &lt;strong&gt;User&lt;/strong&gt; to &lt;strong&gt;SalesPerson&lt;/strong&gt;. As I said, &lt;strong&gt;User.Name&lt;/strong&gt; is actually &lt;strong&gt;UserRegistration.UserName&lt;/strong&gt;, so we’ll add a &lt;strong&gt;UserName&lt;/strong&gt; property to &lt;strong&gt;SalesPerson&lt;/strong&gt;. We can use the &lt;strong&gt;Name&lt;/strong&gt; property for the person’s actual name.&lt;/p&gt;  &lt;p&gt;Before we can add &lt;strong&gt;SalesPersons&lt;/strong&gt; we need &lt;strong&gt;SalesTeams&lt;/strong&gt;. Add a&lt;strong&gt; SalesTeam Editable Grid Screen&lt;/strong&gt;:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_12.png"&gt;&lt;img style="border-bottom: 0px solid; border-left: 0px solid; display: inline; border-top: 0px solid; border-right: 0px solid" title="image" alt="image" src="/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_thumb_5.png" width="644" height="472" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Add some &lt;strong&gt;SalesTeams&lt;/strong&gt;:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_16.png"&gt;&lt;img style="border-bottom: 0px solid; border-left: 0px solid; display: inline; border-top: 0px solid; border-right: 0px solid" title="image" alt="image" src="/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_thumb_7.png" width="625" height="484" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Save them and create a&lt;strong&gt; SalesPerson Editable Grid Screen&lt;/strong&gt; where we find we can select the &lt;strong&gt;Sales Team&lt;/strong&gt; when we create a &lt;strong&gt;Sales Person&lt;/strong&gt;:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_18.png"&gt;&lt;img style="border-bottom: 0px solid; border-left: 0px solid; display: inline; border-top: 0px solid; border-right: 0px solid" title="image" alt="image" src="/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_thumb_8.png" width="644" height="362" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;The point of&lt;strong&gt; SalesPersons.UserName&lt;/strong&gt; is to map to &lt;strong&gt;UserRegistration.UserName&lt;/strong&gt; so at run time we can tell which &lt;strong&gt;SalesPerson&lt;/strong&gt; we are dealing with by matching &lt;strong&gt;Application.User.Name&lt;/strong&gt; to &lt;strong&gt;SalesPerson.UserName&lt;/strong&gt;. This in effect gives us the ability to create relationships between &lt;strong&gt;User&lt;/strong&gt; and other tables; In this case a many-to-one relationship to &lt;strong&gt;SalesTeam.&lt;/strong&gt; You could also create one-to-many relationships, such as a scenario where a &lt;strong&gt;SalesPerson&lt;/strong&gt; got an individualized commission on each &lt;strong&gt;Sale&lt;/strong&gt; made by the team requiring a one-to-many relationship between &lt;strong&gt;SalesPerson&lt;/strong&gt; and &lt;strong&gt;Commissions&lt;/strong&gt;. &lt;/p&gt;  &lt;p&gt;When we create a new &lt;strong&gt;SalesPerson…&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_22.png"&gt;&lt;img style="border-bottom: 0px solid; border-left: 0px solid; display: inline; border-top: 0px solid; border-right: 0px solid" title="image" alt="image" src="/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_thumb_10.png" width="644" height="428" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;…if necessary we also create a new &lt;strong&gt;UserRegistration. &lt;/strong&gt;We don’t want to deal with passwords, so we set it to some default value the user should change the first time they log on:&lt;/p&gt;  &lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #ffffff; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;namespace&lt;/span&gt; LightSwitchApplication
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; partial &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; ApplicationDataService
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;    {
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;        partial &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; SalesPersons_Inserting(SalesPerson entity)
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;            var reg = (from regs &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.DataWorkspace.SecurityData.UserRegistrations
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;                       where regs.UserName == entity.UserName
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;                       select regs).FirstOrDefault();
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (reg == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;            {
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;                var newUser = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.DataWorkspace.SecurityData.UserRegistrations.AddNew();
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;                newUser.UserName = entity.UserName;
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;                newUser.FullName = entity.Name;
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;                newUser.Password = "&lt;span style="color: #8b0000"&gt;changeme/123&lt;/span&gt;";
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;                &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.DataWorkspace.SecurityData.SaveChanges();
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;            }
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;        }
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;    }
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;If we now go to &lt;strong&gt;Administration/Users&lt;/strong&gt; we find the new &lt;strong&gt;User&lt;/strong&gt; there.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_24.png"&gt;&lt;img style="border-bottom: 0px solid; border-left: 0px solid; display: inline; border-top: 0px solid; border-right: 0px solid" title="image" alt="image" src="/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_thumb_11.png" width="644" height="476" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;When launched from &lt;strong&gt;Visual Studio&lt;/strong&gt;, the logged-on user is always&lt;strong&gt; TestUser&lt;/strong&gt;, so we’ll create add a &lt;strong&gt;SalesPerson&lt;/strong&gt; to&lt;strong&gt; Red Team&lt;/strong&gt; with that &lt;strong&gt;UserName&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_26.png"&gt;&lt;img style="border-bottom: 0px solid; border-left: 0px solid; display: inline; border-top: 0px solid; border-right: 0px solid" title="image" alt="image" src="/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_thumb_12.png" width="644" height="340" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Now we need something to test. The point of belonging to a &lt;strong&gt;SalesTeam&lt;/strong&gt; is that you have access to whatever the &lt;strong&gt;SalesTeam&lt;/strong&gt; has access to. So we’ll create a &lt;strong&gt;Sale&lt;/strong&gt; entity with a many-to-one relationship to &lt;strong&gt;SalesTeam&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_28.png"&gt;&lt;img style="border-bottom: 0px solid; border-left: 0px solid; display: inline; border-top: 0px solid; border-right: 0px solid" title="image" alt="image" src="/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_thumb_13.png" width="838" height="772" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Create an &lt;strong&gt;Editable Grid Screen&lt;/strong&gt; for &lt;strong&gt;Sales&lt;/strong&gt; and add some:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_30.png"&gt;&lt;img style="border-bottom: 0px solid; border-left: 0px solid; display: inline; border-top: 0px solid; border-right: 0px solid" title="image" alt="image" src="/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_thumb_14.png" width="644" height="373" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Now you can see I’ve added &lt;strong&gt;Sales&lt;/strong&gt; for both teams. For obvious reasons, team members would not be allowed access to this screen. So we’ll add another&lt;strong&gt; Editable Grid Screen&lt;/strong&gt; and filter it by the &lt;strong&gt;SalesTeam &lt;/strong&gt;of the logged-in &lt;strong&gt;User&lt;/strong&gt;. There’s a couple of ways we could do this. We could go ahead and create the screen and then modify the query, but I’m going to go ahead and create the query and then generate a screen based on the query.&lt;/p&gt;

&lt;p&gt;Right-Click the&lt;strong&gt; Sales Data Source&lt;/strong&gt; and select &lt;strong&gt;Add&lt;/strong&gt; &lt;strong&gt;Query&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_32.png"&gt;&lt;img style="border-bottom: 0px solid; border-left: 0px solid; display: inline; border-top: 0px solid; border-right: 0px solid" title="image" alt="image" src="/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_thumb_15.png" width="644" height="446" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;And there are a couple of ways to write the query to restrict &lt;strong&gt;Sales&lt;/strong&gt; to only those belonging to the same &lt;strong&gt;SalesTeam&lt;/strong&gt; as the logged-on &lt;strong&gt;SalesPerson&lt;/strong&gt; &lt;strong&gt;/&lt;/strong&gt; &lt;strong&gt;User&lt;/strong&gt;. &lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;A ‘pre-process’ query that runs before the query we’re modifying &lt;/li&gt;

  &lt;li&gt;A &lt;strong&gt;Global Variable&lt;/strong&gt; that we can add as a filter. &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;The Pre-Process Query&lt;/h2&gt;

&lt;p&gt;To add the pre-process query, &lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_34.png"&gt;&lt;img style="border-bottom: 0px solid; border-left: 0px solid; display: inline; border-top: 0px solid; border-right: 0px solid" title="image" alt="image" src="/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_thumb_16.png" width="1028" height="269" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;In the query we find the &lt;strong&gt;SalesPerson&lt;/strong&gt; associated with the logged on &lt;strong&gt;User&lt;/strong&gt;. This gives us the &lt;strong&gt;SalesTeam&lt;/strong&gt; and thereby a means to select only &lt;strong&gt;Sales&lt;/strong&gt; linked to the same &lt;strong&gt;SalesTeam&lt;/strong&gt; as the &lt;strong&gt;SalesPerson / User&lt;/strong&gt;.:&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #ffffff; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;partial &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; UserSalesTeamSales_PreprocessQuery(&lt;span style="color: #0000ff"&gt;ref&lt;/span&gt; IQueryable&lt;sale /&gt; query)
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;    SalesPerson person = (from persons &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.DataWorkspace.ApplicationData.SalesPersons
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;                            where persons.UserName == Application.Current.User.Name
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;                            select persons).FirstOrDefault();
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; salesTeamId = person == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; ? -1 : person.SalesTeam.Id;
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;    query = from theSales &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; query
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;            where theSales.SalesTeam.Id == salesTeamId
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;            select theSales;
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Now we create the screen:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_36.png"&gt;&lt;img style="border-bottom: 0px solid; border-left: 0px solid; display: inline; border-top: 0px solid; border-right: 0px solid" title="image" alt="image" src="/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_thumb_17.png" width="1021" height="772" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;The first thing I see is that when logged-in as &lt;strong&gt;TestUser&lt;/strong&gt; I can only see &lt;strong&gt;Red&lt;/strong&gt; &lt;strong&gt;Team&lt;/strong&gt; &lt;strong&gt;Sales&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_38.png"&gt;&lt;img style="border-bottom: 0px solid; border-left: 0px solid; display: inline; border-top: 0px solid; border-right: 0px solid" title="image" alt="image" src="/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_thumb_18.png" width="598" height="484" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;If I go to the&lt;strong&gt; Editable Sales Persons Grid&lt;/strong&gt; I find that &lt;strong&gt;TestUser&lt;/strong&gt; should be restricted to &lt;strong&gt;Red Team&lt;/strong&gt; sales. So far so good:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_42.png"&gt;&lt;img style="border-bottom: 0px solid; border-left: 0px solid; display: inline; border-top: 0px solid; border-right: 0px solid" title="image" alt="image" src="/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_thumb_20.png" width="644" height="359" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;If I change the&lt;strong&gt; Sales Team&lt;/strong&gt; to &lt;strong&gt;Blue Team&lt;/strong&gt;, click &lt;strong&gt;Save&lt;/strong&gt;, go back to &lt;strong&gt;Editable User Sales Team Sales Grid&lt;/strong&gt; and click &lt;strong&gt;Refresh&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_44.png"&gt;&lt;img style="border-bottom: 0px solid; border-left: 0px solid; display: inline; border-top: 0px solid; border-right: 0px solid" title="image" alt="image" src="/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_thumb_21.png" width="532" height="484" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;I find that &lt;strong&gt;TestUser&lt;/strong&gt; now is restricted to&lt;strong&gt; Blue Team Sales&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;The Global Variable Query Parameter&lt;/h2&gt;

&lt;p&gt;The scary thing about creating a&lt;strong&gt; Global Variable&lt;/strong&gt; is that you have to modify an lsml file, which can disable the designer and lead to strange error messages if mishandled, so we have to proceed with care. First, switch to file view:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_46.png"&gt;&lt;img style="border-bottom: 0px solid; border-left: 0px solid; display: inline; border-top: 0px solid; border-right: 0px solid" title="image" alt="image" src="/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_thumb_22.png" width="644" height="484" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;We’re going to edit&lt;strong&gt; Common/ ApplicationDefinition.lsml&lt;/strong&gt;. You may want to back up the file first. &lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_50.png"&gt;&lt;img style="border-bottom: 0px solid; border-left: 0px solid; display: inline; border-top: 0px solid; border-right: 0px solid" title="image" alt="image" src="/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_thumb_24.png" width="591" height="484" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You may get a Catastrophic failure when you try to edit this file. I discovered that if I first opened this one under data, then closed it I was able to edit the one under Common. If you look at properties you’ll find they both map to the same file, the one under data.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_39.png"&gt;&lt;img style="background-image: none; border-bottom: 0px solid; border-left: 0px solid; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px solid; border-right: 0px solid; padding-top: 0px" title="image" alt="image" src="/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_thumb.png" width="488" height="511" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Insert the following &lt;strong&gt;GlobalValueContainerDefinition&lt;/strong&gt; element after the initial &lt;strong&gt;ModelFragment&lt;/strong&gt; element tag as shown below:&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;&lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;ModelFragment&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/LightSwitch/2010/xaml/model"&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;               &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;x&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/winfx/2006/xaml"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;  &lt;span style="color: #0000ff"&gt;&lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;GlobalValueContainerDefinition&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"GlobalSalesTeamInfo"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;&lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;GlobalValueDefinition&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"UserSalesTeamId"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ReturnType&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;":Int32"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;      &lt;span style="color: #0000ff"&gt;&lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;GlobalValueDefinition.Attributes&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;&lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;DisplayName&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Value&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"User SalesTeam ID"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;&lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Description&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Value&lt;/span&gt; =&lt;span style="color: #0000ff"&gt;"Gets the logged on User's SalesTeam ID."&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;      &lt;span style="color: #0000ff"&gt;&lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;GlobalValueDefinition.Attributes&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;&lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;GlobalValueDefinition&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;  &lt;span style="color: #0000ff"&gt;&lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;GlobalValueContainerDefinition&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Now you have to provide the code behind the variable. Create a new class in the &lt;strong&gt;Common&lt;/strong&gt; folder named &lt;strong&gt;GlobalSalesTeamInfo&lt;/strong&gt;. When created there will be a bunch of using statements at the top that show errors. Replace everything with this:&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #ffffff; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System;
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Collections.Generic;
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Linq;
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Text;
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; Microsoft.LightSwitch;
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;namespace&lt;/span&gt; LightSwitchApplication
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; GlobalSalesTeamInfo
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;    {
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; UserSalesTeamId()
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;            SalesPerson person = (from persons &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; Application.Current.CreateDataWorkspace().ApplicationData.SalesPersons
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;                                  where persons.UserName == Application.Current.User.Name
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;                                  select persons).FirstOrDefault();
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; person != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; ? person.SalesTeam.Id : -1;
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;        }
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;    }
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Now we need to switch to logical view so we can modify the query to use this new variable. But when we do the designer will throw a hissy and tell you that you must reload. Once upon a time you could right-click in &lt;strong&gt;Solution&lt;/strong&gt; &lt;strong&gt;Explorer &lt;/strong&gt;and reload from there. Now, if you’re lucky, &lt;strong&gt;BindingToUsersTable&lt;/strong&gt; &lt;strong&gt;Designer&lt;/strong&gt; will be in a tab at the top. Click on that tab and you’ll get a page with a &lt;strong&gt;Reload&lt;/strong&gt; button. If you can’t get to that tab the only other way I know is to reload the solution. In other words, you need for the screen designer to be open in a tab when you edit the .lsml file. That way, when you need to reload, the tab will be there to select. In my experience once you change the .lsml file the &lt;strong&gt;Solution&lt;/strong&gt; &lt;strong&gt;Explorer&lt;/strong&gt; is hosed as far as the logical view, so you can’t get to the designer. Actually I didn’t think of the &lt;strong&gt;View&lt;/strong&gt; menu. Anyway, don’t panic when you start getting all the incomprehensible messages. At best you have to exit and restart. At worst you have to exit, restore the .lsml file, and restart.&lt;/p&gt;

&lt;p&gt;Back in logical view, open the &lt;strong&gt;UserSalesTeamSales&lt;/strong&gt; query:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_52.png"&gt;&lt;img style="border-bottom: 0px solid; border-left: 0px solid; display: inline; border-top: 0px solid; border-right: 0px solid" title="image" alt="image" src="/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_thumb_25.png" width="644" height="467" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;We can now filter on &lt;strong&gt;User Sales Team&lt;/strong&gt; &lt;strong&gt;ID&lt;/strong&gt;. (&lt;strong&gt;LightSwitch&lt;/strong&gt; insists on breaking the name up into words).&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_54.png"&gt;&lt;img style="border-bottom: 0px solid; border-left: 0px solid; display: inline; border-top: 0px solid; border-right: 0px solid" title="image" alt="image" src="/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_thumb_26.png" width="644" height="397" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Get rid of the pre-process query:&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #ffffff; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #008000"&gt;//partial void UserSalesTeamSales_PreprocessQuery(ref IQueryable&lt;sale /&gt; query)&lt;/span&gt;
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #008000"&gt;//{&lt;/span&gt;
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #008000"&gt;// SalesPerson person = (from persons in this.DataWorkspace.ApplicationData.SalesPersons&lt;/span&gt;
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #008000"&gt;// where persons.UserName == Application.Current.User.Name&lt;/span&gt;
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #008000"&gt;// select persons).FirstOrDefault();&lt;/span&gt;
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #008000"&gt;// int salesTeamId = person == null ? -1 : person.SalesTeam.Id;&lt;/span&gt;
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #008000"&gt;// query = from theSales in query&lt;/span&gt;
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #008000"&gt;// where theSales.SalesTeam.Id == salesTeamId&lt;/span&gt;
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #008000"&gt;// select theSales;&lt;/span&gt;
&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;
&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'courier new',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #008000"&gt;//}&lt;/span&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;And sure enough I get the same results when I switch &lt;strong&gt;TestUser’s&lt;/strong&gt; team membership.&lt;/p&gt;

&lt;p&gt;The advantage of the &lt;strong&gt;Global&lt;/strong&gt; &lt;strong&gt;Variable&lt;/strong&gt; approach is that it’s simpler to add the filter to each query that needs it, as you can see above, than it is to write a custom pre-process query for every query that needs to filter on &lt;strong&gt;SalesTeam&lt;/strong&gt; membership as you can see in the now commented-out code immediately above.&lt;/p&gt;

&lt;h2&gt;Testing Other Users&lt;/h2&gt;

&lt;p&gt;To really test, we need to deploy the application so we can log in as different &lt;strong&gt;Users&lt;/strong&gt;. When you do, you’ll find that all your &lt;strong&gt;Users&lt;/strong&gt; and data have disappeared, so we’ll have to create new &lt;strong&gt;SalesTeams&lt;/strong&gt;, &lt;strong&gt;SalesPersons&lt;/strong&gt;, and &lt;strong&gt;Sales&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_56.png"&gt;&lt;img style="border-bottom: 0px solid; border-left: 0px solid; display: inline; border-top: 0px solid; border-right: 0px solid" title="image" alt="image" src="/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_thumb_27.png" width="644" height="418" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;We’ll log in as a &lt;strong&gt;Blue Team Member&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_58.png"&gt;&lt;img style="border-bottom: 0px solid; border-left: 0px solid; display: inline; border-top: 0px solid; border-right: 0px solid" title="image" alt="image" src="/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_thumb_28.png" width="644" height="317" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;And we only see &lt;strong&gt;Blue Team Sales&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_62.png"&gt;&lt;img style="border-bottom: 0px solid; border-left: 0px solid; display: inline; border-top: 0px solid; border-right: 0px solid" title="image" alt="image" src="/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_thumb_30.png" width="644" height="300" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Now we log in as a &lt;strong&gt;Red Team Member&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_64.png"&gt;&lt;img style="border-bottom: 0px solid; border-left: 0px solid; display: inline; border-top: 0px solid; border-right: 0px solid" title="image" alt="image" src="/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_thumb_31.png" width="644" height="319" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;And we’re restricted to &lt;strong&gt;Red Team Sales&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lightswitchhelpwebsite.com/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_66.png"&gt;&lt;img style="border-bottom: 0px solid; border-left: 0px solid; display: inline; border-top: 0px solid; border-right: 0px solid" title="image" alt="image" src="/Portals/0/Blog/Files/2/19/Windows-Live-Writer-BindingaLightSwitchEntitytotheUsersTable_AAC9-image_thumb_32.png" width="644" height="335" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So there you have it. In a less restricted application you’d want to make the Entity associated with &lt;strong&gt;User&lt;/strong&gt; a little more generic, such as &lt;strong&gt;Person, &lt;/strong&gt;so they could participate in a variety of scenarios but always be identifiable as an individual &lt;strong&gt;User&lt;/strong&gt;. Which means a more succinct example would be a Global Variable that identifies the &lt;strong&gt;User/Person&lt;/strong&gt;. Here I use the example of &lt;strong&gt;SalesPerson&lt;/strong&gt;. I’ve added the &lt;strong&gt;UserSalesPersonID&lt;/strong&gt; &lt;strong&gt;GlobalValueDefinition&lt;/strong&gt; to &lt;strong&gt;Application&lt;/strong&gt;&lt;strong&gt;Definition&lt;/strong&gt;.&lt;strong&gt;lsml&lt;/strong&gt;. &lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;&lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;ModelFragment&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/LightSwitch/2010/xaml/model"&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;               &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;x&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"http://schemas.microsoft.com/winfx/2006/xaml"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;  &lt;span style="color: #0000ff"&gt;&lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;GlobalValueContainerDefinition&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"GlobalSalesTeamInfo"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;&lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;GlobalValueDefinition&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"UserSalesTeamId"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ReturnType&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;":Int32"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;      &lt;span style="color: #0000ff"&gt;&lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;GlobalValueDefinition.Attributes&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;&lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;DisplayName&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Value&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"User SalesTeam ID"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;&lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Description&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Value&lt;/span&gt; =&lt;span style="color: #0000ff"&gt;"Gets the logged on User's SalesTeam ID."&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;      &lt;span style="color: #0000ff"&gt;&lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;GlobalValueDefinition.Attributes&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;&lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;GlobalValueDefinition&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;&lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;GlobalValueDefinition&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"UserSalesPersonId"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ReturnType&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;":Int32"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;      &lt;span style="color: #0000ff"&gt;&lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;GlobalValueDefinition.Attributes&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;&lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;DisplayName&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Value&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"User SalesPerson ID"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;&lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Description&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Value&lt;/span&gt; =&lt;span style="color: #0000ff"&gt;"Gets the logged on User's SalesPerson ID."&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;      &lt;span style="color: #0000ff"&gt;&lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;GlobalValueDefinition.Attributes&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;&lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;GlobalValueDefinition&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;  &lt;span style="color: #0000ff"&gt;&lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;GlobalValueContainerDefinition&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Visual Studio was particularly cranky about these changes. I had to reload the solution twice, once because I made a mistake and it wouldn’t recognize that I had fixed it. The second time I don’t know why. The change was what you see above and I could reload in the designer, but Logical View would not come up. After I reloaded the solution, there it was. So don’t assume you’ve made a mistake when Logical View won’t come up, even if you hit the designer reload button.&lt;/p&gt;

&lt;p&gt;Here’s the code behind &lt;strong&gt;UserSalesPersonId&lt;/strong&gt;. I’ve kept UserSalesTeamId because it’s still what I really need, but you can see that you could spin off &lt;strong&gt;Global&lt;/strong&gt; &lt;strong&gt;Variables&lt;/strong&gt; for every relationship that the logged-on user is involved from the one core method &lt;strong&gt;LoggedOnPerson&lt;/strong&gt;()&lt;strong&gt; .&lt;/strong&gt;&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;namespace&lt;/span&gt; LightSwitchApplication
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; GlobalSalesTeamInfo
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; UserSalesPersonId()
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            SalesPerson person = LoggedOnPerson();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; person != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; ? person.Id : -1;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; UserSalesTeamId()
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            SalesPerson person = LoggedOnPerson();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; person != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; ? person.SalesTeam.Id : -1;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; SalesPerson LoggedOnPerson()
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; (from persons &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; Application.Current.CreateDataWorkspace().ApplicationData.SalesPersons
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                              where persons.UserName == Application.Current.User.Name
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;                              select persons).FirstOrDefault();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;        }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;The LightSwitch project is available at &lt;a title="http://lightswitchhelpwebsite.com/Downloads.aspx" href="http://richardwaddell.adefwebserver.com/BindingToUsersTable.zip" target="_blank"&gt;http://lightswitchhelpwebsite.com/Downloads.aspx&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;a href=http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/19/LightSwitch-Creating-a-Relationship-on-current-User-through-SecurityData-UserRegistrations-Table.aspx&gt;More ...&lt;/a&gt;</description>
      <author>webmaster@adefwebserver.com</author>
      <comments>http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/19/LightSwitch-Creating-a-Relationship-on-current-User-through-SecurityData-UserRegistrations-Table.aspx#Comments</comments>
      <slash:comments>43</slash:comments>
      <guid isPermaLink="true">http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/19/LightSwitch-Creating-a-Relationship-on-current-User-through-SecurityData-UserRegistrations-Table.aspx</guid>
      <pubDate>Fri, 06 May 2011 01:40:00 GMT</pubDate>
      <trackback:ping>http://lightswitchhelpwebsite.comDesktopModules/BlogTrackback.aspx?id=19</trackback:ping>
    </item>
  </channel>
</rss>