<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Beth Massi - Sharing the goodness that is VB : Entity Framework</title><link>http://blogs.msdn.com/bethmassi/archive/tags/Entity+Framework/default.aspx</link><description>Tags: Entity Framework</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>New “How Do I” Videos Released on Entity Framework &amp; WPF</title><link>http://blogs.msdn.com/bethmassi/archive/2009/08/26/new-how-do-i-videos-released-on-entity-framework-wpf.aspx</link><pubDate>Wed, 26 Aug 2009 20:18:08 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9885620</guid><dc:creator>Beth Massi</dc:creator><slash:comments>4</slash:comments><comments>http://blogs.msdn.com/bethmassi/comments/9885620.aspx</comments><wfw:commentRss>http://blogs.msdn.com/bethmassi/commentrss.aspx?PostID=9885620</wfw:commentRss><wfw:comment>http://blogs.msdn.com/bethmassi/rsscomments.aspx?PostID=9885620</wfw:comment><description>&lt;p&gt;Yesterday we released a couple more videos onto the &lt;a href="http://msdn.com/vbasic"&gt;Visual Basic Developer Center&lt;/a&gt; on building WPF data-entry forms with Entity Framework:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/vbasic/ee364700.aspx"&gt;How Do I: Hook Up and Display Validation in WPF using Entity Framework?&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/vbasic/ee364701.aspx"&gt;How Do I: Build a WPF Master-Detail Data Entry Form Using Entity Framework?&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;That makes 5 videos total on &lt;a href="http://msdn.microsoft.com/en-us/vbasic/bb466226.aspx#wpfentity"&gt;working with EF in WPF applications&lt;/a&gt;. Others released previously:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/vbasic/dd776537.aspx"&gt;How Do I: Get Started with Entity Framework in WPF Applications?&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/vbasic/dd776540.aspx"&gt;How Do I: Build a WPF Data Entry Form Using Entity Framework?&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/vbasic/dd776544.aspx"&gt;How Do I: Create a WPF Lookup Combobox using Entity Framework?&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;These videos are based on articles I’ve posted here in the past. So if you like reading better that watching videos here you go:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://blogs.msdn.com/bethmassi/archive/2009/04/30/data-binding-wpf-lookup-combobox-values-to-ef-entities.aspx"&gt;Data Binding WPF Lookup Combobox Values to EF Entities&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/bethmassi/archive/2009/05/04/notifying-the-ui-when-entity-references-change-in-lookup-comboboxes.aspx"&gt;Notifying the UI when Entity References Change in Lookup Comboboxes&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/bethmassi/archive/2009/05/08/using-the-wpf-observablecollection-with-ef-entities.aspx"&gt;Using the WPF ObservableCollection with EF Entities&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/bethmassi/archive/2009/07/07/implementing-validation-in-wpf-on-entity-framework-entities.aspx"&gt;Implementing Validation in WPF on Entity Framework Entities&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/bethmassi/archive/2009/07/14/master-detail-data-binding-in-wpf-with-entity-framework.aspx"&gt;Master-Detail Data Binding in WPF with Entity Framework&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/bethmassi/archive/2009/07/16/filtering-entity-framework-collections-in-master-detail-forms.aspx"&gt;Filtering Entity Framework Collections in Master-Detail Forms&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;There are also additional resources listed on the How Do I video pages themselves pointing to topics in the MSDN Library.&lt;/p&gt;  &lt;p&gt;Enjoy!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9885620" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Visual+Basic/default.aspx">Visual Basic</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/WPF/default.aspx">WPF</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/VS2008/default.aspx">VS2008</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Videos/default.aspx">Videos</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/DevCenter/default.aspx">DevCenter</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Data/default.aspx">Data</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Entity+Framework/default.aspx">Entity Framework</category></item><item><title>Using the ReportViewer with ADO.NET Data Services and Entity Framework</title><link>http://blogs.msdn.com/bethmassi/archive/2009/08/19/using-the-reportviewer-with-ado-net-data-services-and-entity-framework.aspx</link><pubDate>Thu, 20 Aug 2009 07:57:20 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9876342</guid><dc:creator>Beth Massi</dc:creator><slash:comments>12</slash:comments><comments>http://blogs.msdn.com/bethmassi/comments/9876342.aspx</comments><wfw:commentRss>http://blogs.msdn.com/bethmassi/commentrss.aspx?PostID=9876342</wfw:commentRss><wfw:comment>http://blogs.msdn.com/bethmassi/rsscomments.aspx?PostID=9876342</wfw:comment><description>&lt;p&gt;The &lt;a href="http://msdn.microsoft.com/en-us/library/ms251671.aspx" target="_blank"&gt;Winforms ReportViewer&lt;/a&gt; in Visual Studio Pro will allow you define client reports with a variety of data sources. If you’re not familiar with creating client-side reports using the ReportViewer, take a look at these videos:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/vbasic/ee309360.aspx" target="_blank"&gt;How Do I: Create a report from a database?&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/vbasic/dd638039.aspx" target="_blank"&gt;How Do I: Create a report from a business object?&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;(The ReportViewer can also display server-based reports a la SQL Reporting Services and has a whole boatload of features that I’m not going to talk about here. For more information on this freely redistributable control, please read &lt;a href="http://msdn.microsoft.com/en-us/library/ms251671.aspx" target="_blank"&gt;ReportViewer Controls (Visual Studio)&lt;/a&gt; in the MSDN library.)&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/data/bb931106.aspx" target="_blank"&gt;ADO.NET Data Services&lt;/a&gt; was released with &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=FBEE1648-7106-44A7-9649-6D9F6D58056E&amp;amp;displaylang=en" target="_blank"&gt;Visual Studio 2008 SP1&lt;/a&gt; and is basically a framework for exposing your data models via RESTful web services. So if you are building a remote CRUD data access layer then this is a technology that will make that super-simple, especially if you just want to expose a few data entities as read-only report sources. (I’ve written a lot about how to use ADO.NET Data Services in a variety of ways &lt;a href="http://blogs.msdn.com/bethmassi/archive/tags/ADO.NET+Data+Services/Article/default.aspx" target="_blank"&gt;so check out these posts if you’re interested&lt;/a&gt;.) Entity Framework was released at the same time and you can use EF as the data model behind your ADO.NET Data Service and expose it easily. If you’ve never created one before, &lt;a href="http://msdn.microsoft.com/en-us/library/cc668796.aspx" target="_blank"&gt;check out this quick start here&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;What’s the Problem?&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;If you’ve ever tried to use the ReportViewer to design a client-side report with an &lt;a href="http://msdn.microsoft.com/en-us/data/bb931106.aspx" target="_blank"&gt;ADO.NET Data Service&lt;/a&gt; data source (or use an &lt;a href="http://msdn.microsoft.com/en-us/library/bb738482.aspx" target="_blank"&gt;Entity Data Model&lt;/a&gt; directly) you may be disappointed. If you try to design a new report, the wizard may crash Visual Studio when selecting an entity. Yikes! &lt;/p&gt;  &lt;p&gt;Let me show you what I mean, but don’t try this at home. I have an ADO.NET Data Service based on the Northwind database &lt;a href="http://blogs.msdn.com/bethmassi/archive/2009/01/09/using-ado-net-data-services.aspx" target="_blank"&gt;&lt;strong&gt;like the one I created here&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;&amp;#160;&lt;/strong&gt;and &lt;a href="http://msdn.microsoft.com/en-us/library/cc668796.aspx" target="_blank"&gt;in the quick start&lt;/a&gt;. I then added a Windows Forms client project to the same solution (File –&amp;gt; Add –&amp;gt; New Project, then select Windows Forms App). Now open Form1 in the client and from the toolbox under the Reporting tab, drop the Microsoft ReportViewer control onto the form and from the smart tag select “Design a New Report”. &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;a href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/UsingtheReportViewerwith.NETDataServices_BC9A/image_2.png"&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="176" alt="image" src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/UsingtheReportViewerwith.NETDataServices_BC9A/image_thumb.png" width="429" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;This will open the Report Wizard. The first thing I need to do is tell it what data source to use, so I’ll select Service and click Next. This will open the Add Service Reference dialog box where I can &lt;a href="http://msdn.microsoft.com/en-us/library/cc668183.aspx" target="_blank"&gt;add the reference to my data service&lt;/a&gt; and Visual Studio will generate the proxy objects for me. In this example my service is in the same solution as the client so I can just click the Discover button and Visual Studio will see it. I named it NorthwindService. Click OK then click Finish. &lt;/p&gt;  &lt;p&gt;At this point I’m brought back to the Report Wizard:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/UsingtheReportViewerwith.NETDataServices_BC9A/image_8.png"&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; display: inline; margin: 0px 15px 0px 0px; border-left: 0px; border-bottom: 0px" height="392" alt="image" src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/UsingtheReportViewerwith.NETDataServices_BC9A/image_thumb_3.png" width="433" align="left" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Hmmmm…. I’m a little lost at this point because -- didn’t I just select the data source? Why don’t I see it?&lt;/p&gt;  &lt;p&gt;Maybe I should have added the service reference first from the Solution Explorer instead of through the Report Wizard? You can do that and you’ll get to the same screen at this point.&lt;/p&gt;  &lt;p&gt;So okay, I’ll click the Add Data Source button that’s calling to me. Granted, I like clicking buttons that have the ellipsis (…) on them because I’m always curious to see what’s under them, but this seems redundant.&lt;/p&gt;  &lt;p&gt;This opens the same dialog as before but this time I’ll choose Object instead of Service. I’m choosing object this time because I’m going to try and bind to the client proxy types that were generated for me when I added the service reference. After selecting Object, click Next and expand the service namespace.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/UsingtheReportViewerwith.NETDataServices_BC9A/image_12.png"&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; display: inline; margin: 0px 10px 0px 0px; border-left: 0px; border-bottom: 0px" height="334" alt="image" src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/UsingtheReportViewerwith.NETDataServices_BC9A/image_thumb_5.png" width="434" align="left" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;For this report I want to just display a list of Customers in the system so I’ll select Customers and then click Next. &lt;/p&gt;  &lt;p&gt;Then… then…… are you ready?… you better sit down for this…. click Finish……. wait for it…. wait for it….. not responding…. uh ohhhh….. &lt;/p&gt;  &lt;p&gt;Visual Studio has encountered a problem and needs to close. Darn!&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/UsingtheReportViewerwith.NETDataServices_BC9A/image_14.png"&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="134" alt="image" src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/UsingtheReportViewerwith.NETDataServices_BC9A/image_thumb_6.png" width="247" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Now that was fun. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;How Do I Fix this?&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Unfortunately the Report Wizard in Visual Studio 2008 doesn’t know how to work with many-to-many relationships and that’s exactly what we have defined in our EF Entity Data Model which is what is backing our ADO.NET Data Service. Customers have many CustomerDemographics and vice versa in Northwind. You can actually define a couple classes yourself manually and create a many-to-many association between them:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;Public Class &lt;/span&gt;Class1

    &lt;span style="color: blue"&gt;Private &lt;/span&gt;_class2 &lt;span style="color: blue"&gt;As &lt;/span&gt;List(&lt;span style="color: blue"&gt;Of &lt;/span&gt;Class2)
    &lt;span style="color: blue"&gt;Public ReadOnly Property &lt;/span&gt;Class2() &lt;span style="color: blue"&gt;As &lt;/span&gt;List(&lt;span style="color: blue"&gt;Of &lt;/span&gt;Class2)
        &lt;span style="color: blue"&gt;Get
            Return &lt;/span&gt;_class2
        &lt;span style="color: blue"&gt;End Get
    End Property

End Class

Public Class &lt;/span&gt;Class2

    &lt;span style="color: blue"&gt;Private &lt;/span&gt;_class1 &lt;span style="color: blue"&gt;As &lt;/span&gt;List(&lt;span style="color: blue"&gt;Of &lt;/span&gt;Class1)
    &lt;span style="color: blue"&gt;Public ReadOnly Property &lt;/span&gt;Class1() &lt;span style="color: blue"&gt;As &lt;/span&gt;List(&lt;span style="color: blue"&gt;Of &lt;/span&gt;Class1)
        &lt;span style="color: blue"&gt;Get
            Return &lt;/span&gt;_class1
        &lt;span style="color: blue"&gt;End Get
    End Property

End Class&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Try to use either class above as the data source of the report and it will crash too. Woah! So when the report designer tries to read these associations I’m guessing it gets into an infinite loop walking the association references back and forth and then it crashes. So it’s not an error with the generated proxy objects per se, the root cause is our object model. If I would have chosen Categories instead, it would have worked. &lt;/p&gt;

&lt;p&gt;So what do we do? We could create another layer of classes without the associations on both sides if we wanted and then use those types instead but then we’d have to write code that IMO is pretty useless, just to shape the data again how we want on the client. &lt;/p&gt;

&lt;p&gt;My recommendation is to create a separate data model for your reports that doesn’t have many-to-many associations at all. You’re going to end up with a lot of different looking entities anyways for your reports because they will most likely pull from multiple database Views and/or stored procedures. You’ll always be displaying one side of the many-to-many relationship on paper anyways. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Creating a Reporting Data Model&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So let’s go back to the data service project and add a new Entity Data Model to the web project called NorthwindReport. This time I’ll just select the Customers, Orders and Order Details and all the Views defined in the database. &lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/UsingtheReportViewerwith.NETDataServices_BC9A/image_16.png"&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="434" alt="image" src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/UsingtheReportViewerwith.NETDataServices_BC9A/image_thumb_7.png" width="449" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Next I’ll add the ADO.NET Data Service and call it NorthwindReport and configure it so that we’re only allowing read-only access to our data by setting the entity access rule like so:&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;Imports &lt;/span&gt;System.Data.Services
&lt;span style="color: blue"&gt;Imports &lt;/span&gt;System.Linq
&lt;span style="color: blue"&gt;Imports &lt;/span&gt;System.ServiceModel.Web

&lt;span style="color: blue"&gt;Public Class &lt;/span&gt;NorthwindReport
    &lt;span style="color: blue"&gt;Inherits &lt;/span&gt;DataService(&lt;span style="color: blue"&gt;Of &lt;/span&gt;NorthwindReportEntities)

    &lt;span style="color: blue"&gt;Public Shared Sub &lt;/span&gt;InitializeService(&lt;span style="color: blue"&gt;ByVal &lt;/span&gt;config &lt;span style="color: blue"&gt;As &lt;/span&gt;IDataServiceConfiguration)
        config.SetEntitySetAccessRule(&lt;span style="color: #a31515"&gt;&amp;quot;*&amp;quot;&lt;/span&gt;, EntitySetRights.&lt;strong&gt;AllRead&lt;/strong&gt;)
    &lt;span style="color: blue"&gt;End Sub
End Class&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Now back on the client we can add the service reference to this service instead. After we add the service reference we can run the Report Wizard again by selecting “Design a New Report” smart tag on the ReportViewer control like I showed in the beginning. Select Object as the data source (or Service if you didn’t add the service reference first, then you’ll have to click “Add Data Sources…” again and then select Object) and you should see the list of entities exposed in the NorthwindReport data model. Now when we select Customer, we don’t have a problem.&lt;/p&gt;

&lt;p&gt;Design the report how you like (&lt;a href="http://msdn.microsoft.com/en-us/library/bb558708.aspx" target="_blank"&gt;see the documentation for more details&lt;/a&gt;) by clicking through the wizard and then go back to the smart tag on the ReportViewer and you should see the report you just created in the dropdown. Next go to the code-behind for the form and in the Load handler we just set the BindingSource.DataSource property to the results of the ADO.NET Data Service LINQ query:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;Imports &lt;/span&gt;NorthwindClient.NorthwindReportService

&lt;span style="color: blue"&gt;Public Class &lt;/span&gt;Form1

    &lt;span style="color: blue"&gt;Private Sub &lt;/span&gt;Form1_Load() &lt;span style="color: blue"&gt;Handles MyBase&lt;/span&gt;.Load
        &lt;span style="color: green"&gt;'TODO: put in My.Settings
        &lt;/span&gt;&lt;span style="color: blue"&gt;Dim &lt;/span&gt;uri &lt;span style="color: blue"&gt;As New &lt;/span&gt;Uri(&lt;span style="color: #a31515"&gt;&amp;quot;http://localhost:1933/NorthwindReport.svc/&amp;quot;&lt;/span&gt;)
        &lt;span style="color: green"&gt;'Create the service reference
        &lt;/span&gt;&lt;span style="color: blue"&gt;Dim &lt;/span&gt;db &lt;span style="color: blue"&gt;As New &lt;/span&gt;NorthwindReportEntities(uri)

        &lt;span style="color: green"&gt;'Set the report's DataSource to the results of the query
        &lt;/span&gt;&lt;span style="color: blue"&gt;Me&lt;/span&gt;.BindingSource.DataSource = &lt;span style="color: blue"&gt;From &lt;/span&gt;c &lt;span style="color: blue"&gt;In &lt;/span&gt;db.Customers _
                                      &lt;span style="color: blue"&gt;Where &lt;/span&gt;c.Country = &lt;span style="color: #a31515"&gt;&amp;quot;USA&amp;quot; &lt;/span&gt;_
                                      &lt;span style="color: blue"&gt;Order By &lt;/span&gt;c.CompanyName

        &lt;span style="color: blue"&gt;Me&lt;/span&gt;.ReportViewer1.RefreshReport()
    &lt;span style="color: blue"&gt;End Sub
End Class&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;Now hit F5 to run this baby and you’ll see the report pull the data from the service and display in the form:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/UsingtheReportViewerwith.NETDataServices_BC9A/image_18.png"&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="352" alt="image" src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/UsingtheReportViewerwith.NETDataServices_BC9A/image_thumb_8.png" width="557" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Recap &amp;amp; Resources&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;ADO.NET Data Services are a great way to quickly and easily expose data on the web, especially if it’s just read-only data used for remote reporting clients. The key to using the ReportViewer with ADO.NET Data Services (or an Entity Data Model directly, or even your own object model) is to make sure there are &lt;strong&gt;no &lt;/strong&gt;many-to-many associations on the entities. Here are the resources you need to get started with ReportViewer and ADO.NET Data Services:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/cc668796.aspx" target="_blank"&gt;Data Service Quick Start (ADO.NET Data Services Framework)&lt;/a&gt;&lt;/li&gt;

  &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/cc668183.aspx" target="_blank"&gt;How to: Add, Update, or Remove an ADO.NET Service Reference&lt;/a&gt;&lt;/li&gt;

  &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms251704.aspx" target="_blank"&gt;Configuring ReportViewer for Local Processing&lt;/a&gt;&lt;/li&gt;

  &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/bb558708.aspx" target="_blank"&gt;Report Designer (Visual Studio)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9876342" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/bethmassi/archive/tags/VS2008/default.aspx">VS2008</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/DevCenter/default.aspx">DevCenter</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Article/default.aspx">Article</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Entity+Framework/default.aspx">Entity Framework</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/ADO.NET+Data+Services/default.aspx">ADO.NET Data Services</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Reporting/default.aspx">Reporting</category></item><item><title>Auto Access to non-Indexed Collections : Or How I Learned to Stop Worrying and Love the VB Compiler</title><link>http://blogs.msdn.com/bethmassi/archive/2009/08/14/auto-access-to-non-indexed-collections-or-how-i-learned-to-stop-worrying-and-love-the-vb-compiler.aspx</link><pubDate>Sat, 15 Aug 2009 02:26:35 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9870664</guid><dc:creator>Beth Massi</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/bethmassi/comments/9870664.aspx</comments><wfw:commentRss>http://blogs.msdn.com/bethmassi/commentrss.aspx?PostID=9870664</wfw:commentRss><wfw:comment>http://blogs.msdn.com/bethmassi/rsscomments.aspx?PostID=9870664</wfw:comment><description>&lt;p&gt;I just finished a couple more &lt;a href="http://msdn.microsoft.com/en-us/vbasic/bb466226.aspx#wpfentity" target="_blank"&gt;How Do I videos on using EF with WPF using VS2008 SP1&lt;/a&gt; (they’ll be published soon) and while I was translating my VB code to C# I stumbled upon an error in C# that does not happen in VB. This of course got me curious and so I thought I’d share what I found out.&lt;/p&gt;  &lt;p&gt;I have an EDM defined with a parent entity &lt;b&gt;Order&lt;/b&gt; and child &lt;b&gt;OrderDetails&lt;/b&gt; that I created with the designer – very basic – like I show in &lt;a href="http://msdn.microsoft.com/en-us/vbasic/dd776537.aspx" target="_blank"&gt;this video&lt;/a&gt;. In the example I was working on, I was putting the results of an order query into a generic list but also including the OrderDetails so I end up with an &lt;a href="http://msdn.microsoft.com/en-us/library/bb354106.aspx" target="_blank"&gt;EntityCollection&lt;/a&gt; called OrderDetails on every Order.&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: #2b91af"&gt;OMSEntities &lt;/span&gt;db = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;OMSEntities&lt;/span&gt;();

&lt;span style="color: blue"&gt;var &lt;/span&gt;results = &lt;span style="color: blue"&gt;from &lt;/span&gt;o &lt;span style="color: blue"&gt;in &lt;/span&gt;db.Orders.Include(&lt;span style="color: #a31515"&gt;&amp;quot;OrderDetails&amp;quot;&lt;/span&gt;)
              &lt;span style="color: blue"&gt;select &lt;/span&gt;o;

&lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Order&lt;/span&gt;&amp;gt; orderList = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Order&lt;/span&gt;&amp;gt;(results);&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;However if I want to get the first Order’s first OrderDetail, I get an error in C#: “&lt;strong&gt;&lt;em&gt;Cannot apply indexing with [] to an expression of type 'System.Data.Objects.DataClasses.EntityCollection&amp;lt;EFTestDAL.OrderDetail&amp;gt;&lt;/em&gt;&lt;/strong&gt;'” when I write this line:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: green"&gt;//ERROR
&lt;/span&gt;&lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(orderList[0].OrderDetails[0].OrderDetailID);&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;However, the VB code works perfectly.&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;Dim &lt;/span&gt;db &lt;span style="color: blue"&gt;As New &lt;/span&gt;OMSEntities

&lt;span style="color: blue"&gt;Dim &lt;/span&gt;results = &lt;span style="color: blue"&gt;From &lt;/span&gt;o &lt;span style="color: blue"&gt;In &lt;/span&gt;db.Orders.Include(&lt;span style="color: #a31515"&gt;&amp;quot;OrderDetails&amp;quot;&lt;/span&gt;) _
              &lt;span style="color: blue"&gt;Select &lt;/span&gt;o

&lt;span style="color: blue"&gt;Dim &lt;/span&gt;orderList &lt;span style="color: blue"&gt;As New &lt;/span&gt;List(&lt;span style="color: blue"&gt;Of &lt;/span&gt;Order)(results)

&lt;span style="color: green"&gt;'No Error
&lt;/span&gt;Console.WriteLine(orderList(0).OrderDetails(0).OrderDetailID)&lt;/pre&gt;

&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;So what gives in C#? At first I thought it was something with the way the EntityCollection was being generated in each of the designer code-behind for the languages, maybe I found a bug? So I created a single solution and used C# as the data access layer project and then added a C# client and a VB client project and still the same issue. VB worked fine against the C# defined EntityCollection. Hmmmm…… &lt;/p&gt;

&lt;p&gt;Next Stop, &lt;a href="http://www.bing.com/" target="_blank"&gt;BING&lt;/a&gt;. I searched for the error message and no luck. Okay well it helps to actually read these error messages so let’s put on my glasses and break out my Microsoft Compiler Error Message Magic Translator* and yeah, as the title of this post suggests, the EntityCollection doesn’t actually implement an indexer. Okay so again, why does it work in VB? &lt;/p&gt;

&lt;p&gt;The VB Compiler loves to help. It’s like uber-helpful (sometimes to its own fault, I admit), but this time it’s really helping in a good way. The way to get this to work in C# is to call the &lt;a href="http://msdn.microsoft.com/en-us/library/bb299233.aspx" target="_blank"&gt;ElementAt&lt;/a&gt; or &lt;a href="http://msdn.microsoft.com/en-us/library/bb494386.aspx" target="_blank"&gt;ElementAtOrDefault&lt;/a&gt; extension methods. So in C# to get the OrderDetail by index you write:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: green"&gt;//No ERROR
&lt;/span&gt;&lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(orderList[0].OrderDetails.ElementAt(0).OrderDetailID);&lt;/pre&gt;

&lt;p&gt;So what Visual Basic is doing for you is exactly that. Actually it’s calling ElementAtOrDefault for you if the collection does not implement an indexer of its own. So you can write the same syntax for all collections. This help topic on the &lt;a href="http://msdn.microsoft.com/en-us/library/bb384875.aspx" target="_blank"&gt;Extension Indexer Property&lt;/a&gt; gave us the clue we needed. So, if an IEnumerable or IQueryable doesn't define an indexer property, VB will translate the indexer syntax to the ElementAtOrDefault operator. Good to know!&lt;/p&gt;

&lt;p&gt;So I asked &lt;a href="http://blogs.msdn.com/diego/" target="_blank"&gt;Diego&lt;/a&gt; on the EF team why the EntityCollection doesn’t implement an indexer. I was told that the EF team decided long time ago that since there was conceptually no guarantee on the ordering of EntityCollections, they didn’t want to give the illusion that such ordering existed by exposing an indexer. The internal implementation of EntityCollection(Of T) uses HashSet(Of T), which is super-fast and doesn’t have an indexer.&lt;/p&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;

&lt;p&gt;*No there is no such thing as a Microsoft Compiler Error Message Magic Translator that I know of so please don’t ask! But please feel free to create one on &lt;a href="http://www.codeplex.com" target="_blank"&gt;CodePlex&lt;/a&gt;. ;-)&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9870664" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Visual+Basic/default.aspx">Visual Basic</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/VS2008/default.aspx">VS2008</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/DevCenter/default.aspx">DevCenter</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Article/default.aspx">Article</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Entity+Framework/default.aspx">Entity Framework</category></item><item><title>N-Tier Application Patterns with Entity Framework</title><link>http://blogs.msdn.com/bethmassi/archive/2009/08/05/n-tier-application-patterns-with-entity-framework.aspx</link><pubDate>Thu, 06 Aug 2009 01:20:52 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9858455</guid><dc:creator>Beth Massi</dc:creator><slash:comments>5</slash:comments><comments>http://blogs.msdn.com/bethmassi/comments/9858455.aspx</comments><wfw:commentRss>http://blogs.msdn.com/bethmassi/commentrss.aspx?PostID=9858455</wfw:commentRss><wfw:comment>http://blogs.msdn.com/bethmassi/rsscomments.aspx?PostID=9858455</wfw:comment><description>&lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/magazine/ee310078.aspx" target="_blank"&gt;This month’s MSDN Magazine&lt;/a&gt; has a particularly good article in there by &lt;a href="http://blogs.msdn.com/dsimmons" target="_blank"&gt;Danny Simmons&lt;/a&gt;, Development Manager on the Entity Framework team, on &lt;a href="http://msdn.microsoft.com/en-us/magazine/ee321569.aspx" target="_blank"&gt;&lt;strong&gt;N-Tier Application Patterns with Entity Framework&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;&amp;#160;&lt;/strong&gt;that I recommend reading through. He explains the design considerations you need to take into account when building n-tier applications and also discusses some of the improvements that are coming in .NET Framework 4.0 that will make building n-tier applications with EF much much easier. I’m personally looking forward to self-tracking entities myself, hooray! &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/adonet" target="_blank"&gt;Tim Mallalieu&lt;/a&gt; also has a good &lt;a href="http://msdn.microsoft.com/en-us/magazine/ee236639.aspx" target="_blank"&gt;best practices article&lt;/a&gt; in this issue that I just started digging into regarding the next version of Entity Framework. &lt;/p&gt;  &lt;p&gt;Enjoy!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9858455" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Data/default.aspx">Data</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/N-tier/default.aspx">N-tier</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Entity+Framework/default.aspx">Entity Framework</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/VS2010/default.aspx">VS2010</category></item><item><title>Filtering Entity Framework Collections in Master-Detail Forms</title><link>http://blogs.msdn.com/bethmassi/archive/2009/07/16/filtering-entity-framework-collections-in-master-detail-forms.aspx</link><pubDate>Fri, 17 Jul 2009 03:18:17 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9836309</guid><dc:creator>Beth Massi</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/bethmassi/comments/9836309.aspx</comments><wfw:commentRss>http://blogs.msdn.com/bethmassi/commentrss.aspx?PostID=9836309</wfw:commentRss><wfw:comment>http://blogs.msdn.com/bethmassi/rsscomments.aspx?PostID=9836309</wfw:comment><description>&lt;p&gt;&lt;a href="http://blogs.msdn.com/bethmassi/archive/2009/07/14/master-detail-data-binding-in-wpf-with-entity-framework.aspx" target="_blank"&gt;Last post&lt;/a&gt; I talked about how to get WPF data binding to work with master-detail entity collections. I had a couple readers ask me how they could filter the child collection instead of bringing them all down so in this post I’d like to show how you could do that. It’s actually pretty easy.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Customer (Master) –&amp;lt; Orders (Detail) &lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;I created a very simple Entity Data Model (EDM) that demonstrates a Master-Detail relationship. The Orders table is defined in the database with a non-nullable foreign key CustomerID, meaning that no Order can exist without a Customer. This relationship is inferred by Entity Framework (EF) to set up the navigation properties giving us an Orders EntityCollection on Customer. &lt;/p&gt;  &lt;p&gt;&lt;img src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/DataBindingWPFLookupComboboxValuestoEFEn_F345/image_6.png" /&gt;&lt;/p&gt;  &lt;p&gt;To recap, I’ve created my own ObservableCollection(of Customer) called CustomerCollection so that when the UI modifies the collection through AddItem/RemoveItem, we can instruct the ObjectContext to track these changes so that it will insert and delete entities to the database when we call SaveChanges. &lt;/p&gt;  &lt;p&gt;The constructor takes an IEnumerable(Of Customer) which allows us to pass a LINQ to Entities query into our CustomerCollection. This executes the query against the database when we call the base class’s constructor which iterates over the query results and adds the Customer entities to our collection. &lt;/p&gt;  &lt;p&gt;Take a look &lt;a href="http://blogs.msdn.com/bethmassi/archive/2009/07/14/master-detail-data-binding-in-wpf-with-entity-framework.aspx" target="_blank"&gt;at the first chunk of code in the last post&lt;/a&gt; for the full code listing for the CustomerCollection class. I don’t have to make any changes to it to support filtering the children. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Loading All Detail Entities &lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;If you want to bring down all the Orders for the selected Customer you can use the .Include extension like I’ve shown before using explicit loading. &lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: green"&gt;'EF ObjectContext connects to database and tracks changes
&lt;/span&gt;&lt;span style="color: blue"&gt;Dim &lt;/span&gt;db &lt;span style="color: blue"&gt;As New &lt;/span&gt;OMSEntities
&lt;span style="color: green"&gt;'inherits from ObservableCollection(Of Customer)
&lt;/span&gt;&lt;span style="color: blue"&gt;Dim &lt;/span&gt;CustomerData &lt;span style="color: blue"&gt;As &lt;/span&gt;CustomerCollection

&lt;span style="color: green"&gt;'Include all Orders for Customer #1
&lt;/span&gt;&lt;span style="color: blue"&gt;Dim &lt;/span&gt;customers = &lt;span style="color: blue"&gt;From &lt;/span&gt;c &lt;span style="color: blue"&gt;In &lt;/span&gt;db.Customers.Include(&lt;span style="color: #a31515"&gt;&amp;quot;Orders&amp;quot;&lt;/span&gt;) _
                &lt;span style="color: blue"&gt;Where &lt;/span&gt;c.CustomerID = 1

CustomerData = &lt;span style="color: blue"&gt;New &lt;/span&gt;CustomerCollection(customers, db)&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;This ends up shooting one query to SQL Server to return all the Orders for the selected Customer when we pass the query into our collection. But what if we also wanted to filter the Orders? There’s a couple ways we can do this because of a cool feature of the Entity Framework. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Filtering Detail Entities with a Sub-Query&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When the entities are being created in memory on the client from the query (materialized), the object state manager will attempt to hook up the entity references and collections automatically. This means that all we have to do is specify a filtered query and make sure we execute it by enumerating over the results (or calling ToList). &lt;/p&gt;

&lt;p&gt;So say we wanted to only grab the most recent Orders where the order was placed on or after January 1st, 2009:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;Dim &lt;/span&gt;query = &lt;span style="color: blue"&gt;From &lt;/span&gt;c &lt;span style="color: blue"&gt;In &lt;/span&gt;db.Customers _
            &lt;span style="color: blue"&gt;Where &lt;/span&gt;c.CustomerID = 1 _
            &lt;span style="color: blue"&gt;Select &lt;/span&gt;Customer = c, _
&lt;strong&gt;                   Orders = &lt;span style="color: blue"&gt;From &lt;/span&gt;o &lt;span style="color: blue"&gt;In &lt;/span&gt;c.Orders _
                            &lt;span style="color: blue"&gt;Where &lt;/span&gt;o.OrderDate &amp;gt;= #1/1/2009#
&lt;/strong&gt;
&lt;span style="color: blue"&gt;Dim &lt;/span&gt;customers = &lt;span style="color: blue"&gt;From &lt;/span&gt;item &lt;span style="color: blue"&gt;In &lt;/span&gt;&lt;strong&gt;query.ToList&lt;/strong&gt; &lt;span style="color: blue"&gt;Select &lt;/span&gt;item.Customer

CustomerData = &lt;span style="color: blue"&gt;New &lt;/span&gt;CustomerCollection(customers, db)&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Here I’m specifying a sub-query to only pull the Orders I want on the selected Customer. The first query creates a collection of anonymous types that have a Customer object and a filtered Orders collection. In the following query, I need to call query.ToList in order to execute the query against the database and materialize the objects. This sends one statement to SQL Server like before, but this time it’s filtered on Orders as well.&lt;/p&gt;

&lt;p&gt;At this point the Customers and Orders are in memory and the object state manager has hooked them up for us. Meaning that the Customer now has an Orders collection like we want. As long as we Select the entire Customer and Order types in our queries this will work (as opposed to just selecting specific fields – the entity types have to match up for it to work). The second query is just a LINQ to Objects query (in memory) that we’re using so that we can pass an IEnumerable(Of Customer) to our ObservableCollection. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Filtering Detail Entities with &lt;/strong&gt;&lt;strong&gt;Separate Queries&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There are other ways we could write this. We could write the queries separately:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;Dim &lt;/span&gt;customers = (&lt;span style="color: blue"&gt;From &lt;/span&gt;c &lt;span style="color: blue"&gt;In &lt;/span&gt;db.Customers _
                 &lt;span style="color: blue"&gt;Where &lt;/span&gt;c.CustomerID = 1).ToList()

&lt;span style="color: blue"&gt;Dim &lt;/span&gt;orders = (&lt;span style="color: blue"&gt;From &lt;/span&gt;o &lt;span style="color: blue"&gt;In &lt;/span&gt;db.Orders _
              &lt;span style="color: blue"&gt;Where &lt;/span&gt;o.Customer.CustomerID = 1 &lt;span style="color: blue"&gt;AndAlso &lt;/span&gt;_
                    o.OrderDate &amp;gt; #1/1/2009#).ToList()

CustomerData = &lt;span style="color: blue"&gt;New &lt;/span&gt;CustomerCollection(customers, db)&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Notice that I’m calling ToList to force the queries to execute so that the objects will materialize (come into memory), then I’m just passing the Customers to the constructor because at this point the object state manager has hooked up our entities (Customer has an EntityCollection of Orders based on the filtered query). The results on the client are the same but the major difference here is that &lt;strong&gt;two &lt;/strong&gt;statements are sent to SQL Server, so keep that in mind. I like the first approach better with a sub-query because of the single SQL statement that’s generated as well as the clearer looking LINQ query.&lt;/p&gt;

&lt;p&gt;I’ve updated &lt;a href="http://code.msdn.microsoft.com/Project/Download/FileDownload.aspx?ProjectName=wpfdatavideos&amp;amp;DownloadId=6509" target="_blank"&gt;this &lt;strong&gt;sample application&lt;/strong&gt;&lt;/a&gt; that also shows a variety of other data binding techniques with EF and WPF so have a look. The filter example above is in the SimpleMasterDetailBinding form.&lt;/p&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9836309" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/bethmassi/archive/tags/WPF/default.aspx">WPF</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/LINQ/default.aspx">LINQ</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/VS2008/default.aspx">VS2008</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/DevCenter/default.aspx">DevCenter</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Article/default.aspx">Article</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Entity+Framework/default.aspx">Entity Framework</category></item><item><title>Master-Detail Data Binding in WPF with Entity Framework</title><link>http://blogs.msdn.com/bethmassi/archive/2009/07/14/master-detail-data-binding-in-wpf-with-entity-framework.aspx</link><pubDate>Wed, 15 Jul 2009 02:24:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9833642</guid><dc:creator>Beth Massi</dc:creator><slash:comments>16</slash:comments><comments>http://blogs.msdn.com/bethmassi/comments/9833642.aspx</comments><wfw:commentRss>http://blogs.msdn.com/bethmassi/commentrss.aspx?PostID=9833642</wfw:commentRss><wfw:comment>http://blogs.msdn.com/bethmassi/rsscomments.aspx?PostID=9833642</wfw:comment><description>&lt;P&gt;Today I thought I would talk about a really common scenario in data applications, creating a master-details (one-to-many) data entry form. I’ve written about WPF data binding and Entity Framework a lot in the past:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Posts:&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/bethmassi/archive/2008/12/10/master-details-with-entity-framework-explicit-load.aspx" mce_href="http://blogs.msdn.com/bethmassi/archive/2008/12/10/master-details-with-entity-framework-explicit-load.aspx"&gt;Master-Details with Entity Framework Explicit Load&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/bethmassi/archive/2008/11/07/loading-data-and-binding-controls-in-wpf-with-collectionviewsource.aspx" mce_href="http://blogs.msdn.com/bethmassi/archive/2008/11/07/loading-data-and-binding-controls-in-wpf-with-collectionviewsource.aspx"&gt;Loading Data and Binding Controls in WPF with CollectionViewSource&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/bethmassi/archive/2009/05/08/using-the-wpf-observablecollection-with-ef-entities.aspx" mce_href="http://blogs.msdn.com/bethmassi/archive/2009/05/08/using-the-wpf-observablecollection-with-ef-entities.aspx"&gt;Using the WPF ObservableCollection with EF Entities&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/bethmassi/archive/2009/04/30/data-binding-wpf-lookup-combobox-values-to-ef-entities.aspx" target=_blank mce_href="http://blogs.msdn.com/bethmassi/archive/2009/04/30/data-binding-wpf-lookup-combobox-values-to-ef-entities.aspx"&gt;Data Binding WPF Lookup Combobox Values to EF Entities&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/bethmassi/archive/2009/05/04/notifying-the-ui-when-entity-references-change-in-lookup-comboboxes.aspx" mce_href="http://blogs.msdn.com/bethmassi/archive/2009/05/04/notifying-the-ui-when-entity-references-change-in-lookup-comboboxes.aspx"&gt;Notifying the UI when Entity References Change in Lookup Comboboxes&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/bethmassi/archive/2009/07/07/implementing-validation-in-wpf-on-entity-framework-entities.aspx" mce_href="http://blogs.msdn.com/bethmassi/archive/2009/07/07/implementing-validation-in-wpf-on-entity-framework-entities.aspx"&gt;Implementing Validation in WPF on Entity Framework Entities&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;&lt;STRONG&gt;Videos:&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/vbasic/dd776537.aspx" mce_href="http://msdn.microsoft.com/en-us/vbasic/dd776537.aspx"&gt;How Do I: Get Started with Entity Framework in WPF Applications?&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/vbasic/dd776540.aspx" mce_href="http://msdn.microsoft.com/en-us/vbasic/dd776540.aspx"&gt;How Do I: Build a WPF Data Entry Form Using Entity Framework?&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/vbasic/dd776544.aspx" mce_href="http://msdn.microsoft.com/en-us/vbasic/dd776544.aspx"&gt;How Do I: Create a WPF Lookup Combobox using Entity Framework?&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/vbasic/dd239277.aspx" mce_href="http://msdn.microsoft.com/en-us/vbasic/dd239277.aspx"&gt;How Do I: Create a Master-Detail Data Entry Form in WPF?&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Today I want to pull these concepts together and walk through one way to create a master-detail form in WPF using entities from the Entity Framework. Specifically, we’ll declare CollectionViewSources in our XAML &lt;A href="http://blogs.msdn.com/bethmassi/archive/2008/11/07/loading-data-and-binding-controls-in-wpf-with-collectionviewsource.aspx" target=_blank mce_href="http://blogs.msdn.com/bethmassi/archive/2008/11/07/loading-data-and-binding-controls-in-wpf-with-collectionviewsource.aspx"&gt;like I showed here&lt;/A&gt;, to bind to an ObservableCollection of entities &lt;A href="http://blogs.msdn.com/bethmassi/archive/2009/05/08/using-the-wpf-observablecollection-with-ef-entities.aspx" target=_blank mce_href="http://blogs.msdn.com/bethmassi/archive/2009/05/08/using-the-wpf-observablecollection-with-ef-entities.aspx"&gt;like I showed here&lt;/A&gt;, where the children are explicitly loaded &lt;A href="http://blogs.msdn.com/bethmassi/archive/2008/12/10/master-details-with-entity-framework-explicit-load.aspx" target=_blank mce_href="http://blogs.msdn.com/bethmassi/archive/2008/12/10/master-details-with-entity-framework-explicit-load.aspx"&gt;like I showed here&lt;/A&gt;. Everybody got that? ;-)&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Creating the Entity Data Model&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;First let’s create a simple Entity Data Model (EDM) that demonstrates a Master-Detail relationship. I’ll use a simple database called OMS that has Customer and Orders tables with a non-nullable foreign key set up between them on CustomerID, meaning that no Order can exist without a Customer. This relationship is inferred by Entity Framework (EF) to set up the navigation properties. Notice that there is an Orders EntityCollection on Customer. &lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/DataBindingWPFLookupComboboxValuestoEFEn_F345/image_6.png" mce_src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/DataBindingWPFLookupComboboxValuestoEFEn_F345/image_6.png"&gt; &lt;/P&gt;
&lt;P&gt;What we want to do is build a simple form that will let us Edit, Add, and Delete Customers and their Orders. First let’s set up the WPF Data Binding in XAML. &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Defining the CollectionViewSource and Data Bindings &lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;To recap, a CollectionViewSource is a proxy for the CollectionView which manages the currency (the position) in the list of entities. It has a property called &lt;EM&gt;Source&lt;/EM&gt; which can be set in our code behind. This way, we can set up CollectionVieSources in XAML for all our data lists and bind them to the corresponding controls all in XAML. Then at runtime in our code we set the Source properties and only at that time does the data pull from the database. &lt;/P&gt;
&lt;P&gt;To define a Master-Detail relationship we define two CollectionViewSources one for the master and one for the detail collections. Then on the detail we set the Source property to the master CollectionViewSource and then specify the Path property as the name of the child collection. In our case the name of the collection on Customer is “Orders”. So we can specify the XAML like so:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Window.Resources&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;
    &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;CollectionViewSource &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;x&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;:&lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Key&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="MasterViewSource" /&amp;gt;
    &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;CollectionViewSource &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;x&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;:&lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Key&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="DetailsViewSource" 
                    &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Source&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="{&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Binding &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Source&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;={&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;StaticResource &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;MasterViewSource&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;}, &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Path&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;='Orders'}" /&amp;gt;
&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Window.Resources&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;Now as the position changes in the MasterViewSource to point to a new Customer, the DetailsViewSource will filter automatically to only those related Orders for that Customer. We can now set the rest of the data bindings on the controls on the form by setting the BindingContext of the container controls to the CollectionViewSource we want to display. For example, we can set up a StackPanel to contain the Customer fields and set the StackPanel.DataContext to the MasterViewSource. Under that we can set up a ListView to display the Orders by setting the ListView.ItemsSource to the DetailsViewSource.&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Grid&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;...&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;    &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;StackPanel &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Name&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="StackPanel2" &lt;BR&gt;                &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Grid.Column&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="1" &lt;BR&gt;                &lt;/SPAN&gt;&lt;STRONG&gt;&lt;SPAN style="COLOR: red"&gt;DataContext&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="{&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Binding &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Source&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;={&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;StaticResource &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;MasterViewSource&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN style="COLOR: blue"&gt;&lt;STRONG&gt;}&lt;/STRONG&gt;}"&amp;gt;
        &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;TextBox &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Name&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="TextBox1" &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;IsReadOnly&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="True" 
                 &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Text&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="{&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Binding &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Path&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=CustomerID, &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Mode&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=OneWay}"/&amp;gt;
        &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;TextBox &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Name&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="TextBox5"&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;                 Text&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="{&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Binding &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Path&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=LastName}"/&amp;gt;&lt;BR&gt;...
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;    &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;StackPanel&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;
...&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;    &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;ListView &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Grid.Row&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="3" &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Name&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="ListView1" 
              &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;IsSynchronizedWithCurrentItem&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="True"
&lt;STRONG&gt;              &lt;/STRONG&gt;&lt;/SPAN&gt;&lt;STRONG&gt;&lt;SPAN style="COLOR: red"&gt;ItemsSource&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="{&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Binding &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Source&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;={&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;StaticResource &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;DetailsViewSource&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN style="COLOR: blue"&gt;&lt;STRONG&gt;}}"&amp;gt;
&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;        &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;ListView.View&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;
            &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;GridView&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;
                &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;GridViewColumn &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Header&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="ID" &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Width&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="75"&amp;gt;
                    &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;GridViewColumn.CellTemplate&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;
                        &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;DataTemplate&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;
                        &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Label &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Content&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="{&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Binding &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Path&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=OrderID}" 
                                     &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Margin&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="-6,0,-6,0"/&amp;gt;
                        &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;DataTemplate&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;
                    &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;GridViewColumn.CellTemplate&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;
                &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;GridViewColumn&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;
                &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;GridViewColumn &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Header&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="Order Date" &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Width&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="100"&amp;gt;
                    &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;GridViewColumn.CellTemplate&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;
                        &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;DataTemplate&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;
                            &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;TextBox &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Text&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="{&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Binding &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Path&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=OrderDate}" 
                                     &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Margin&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="-6,0,-6,0"/&amp;gt;
                        &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;DataTemplate&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;
                    &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;GridViewColumn.CellTemplate&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;
                &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;GridViewColumn&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;
...&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P&gt;The only thing we need to do now is set the Source property of the MasterViewSource in code to the collection of our Customer entities. &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Defining the Master-Detail Entities in an ObservableCollection&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;I showed before how we can create a collection of entities that inherits from ObservableCollection &lt;A href="http://blogs.msdn.com/bethmassi/archive/2009/05/08/using-the-wpf-observablecollection-with-ef-entities.aspx" target=_blank mce_href="http://blogs.msdn.com/bethmassi/archive/2009/05/08/using-the-wpf-observablecollection-with-ef-entities.aspx"&gt;in this post&lt;/A&gt; to make it easier to work with WPF data binding. But in that example we were only working with a simple collection of Customers and not their Orders. If you recall, the ObjectContext is what tracks changes on entities so in order for the ObjectContext to be notified that adds and deletes to the ObservableCollection need to be tracked you need to override the InsertItem and RemoveItem methods so that you can tell the ObjectContext to either add or delete the entity which will ultimately execute against the database. In the constructor I pass a reference to the ObjectContext. You can also pass in any collection of entities, say from a LINQ query, and then add them to the ObservableCollection. However, we need to make a couple modifications to our collection so that we can also track the child order entities correctly. &lt;/P&gt;
&lt;P&gt;Adds to the Customer.Orders EntityCollection will will cause the addition of a new Order to the collection as well as the association to Customer automatically. However removing the Order from the Customer.Orders EntityCollection will only &lt;EM&gt;remove the association &lt;/EM&gt;and will not attempt to actually delete the Order from the database. Instead it attempts to set the CustomerID to NULL (to remove the association from the Customer) but since we have referential integrity set up to disallow this we will get an error if we attempt to SaveChanges. &lt;/P&gt;
&lt;P&gt;In a lot of scenarios it makes sense to just remove the association and set the foreign key to NULL in the database. But in this example we really mean to delete the Order record completely when the Order is removed from the collection. So the key is adding an event handler to the AssociationChanged event on the Orders EntityCollection that’s hanging off our Customer entity and telling the ObjectContext to explicitly delete the Order. &lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;Public Class &lt;/SPAN&gt;CustomerCollection
    &lt;SPAN style="COLOR: blue"&gt;Inherits &lt;/SPAN&gt;ObservableCollection(&lt;SPAN style="COLOR: blue"&gt;Of &lt;/SPAN&gt;Customer)

    &lt;SPAN style="COLOR: blue"&gt;Private &lt;/SPAN&gt;_context &lt;SPAN style="COLOR: blue"&gt;As &lt;/SPAN&gt;OMSEntities
    &lt;SPAN style="COLOR: blue"&gt;Public ReadOnly Property &lt;/SPAN&gt;Context() &lt;SPAN style="COLOR: blue"&gt;As &lt;/SPAN&gt;OMSEntities
        &lt;SPAN style="COLOR: blue"&gt;Get
            Return &lt;/SPAN&gt;_context
        &lt;SPAN style="COLOR: blue"&gt;End Get
    End Property


    Sub New&lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;ByVal &lt;/SPAN&gt;customers &lt;SPAN style="COLOR: blue"&gt;As &lt;/SPAN&gt;IEnumerable(&lt;SPAN style="COLOR: blue"&gt;Of &lt;/SPAN&gt;Customer), &lt;SPAN style="COLOR: blue"&gt;ByVal &lt;/SPAN&gt;context &lt;SPAN style="COLOR: blue"&gt;As &lt;/SPAN&gt;OMSEntities)
        &lt;SPAN style="COLOR: blue"&gt;MyBase&lt;/SPAN&gt;.New(customers)
        _context = context

        &lt;SPAN style="COLOR: blue"&gt;For Each &lt;/SPAN&gt;c &lt;SPAN style="COLOR: blue"&gt;In &lt;/SPAN&gt;customers
            &lt;SPAN style="COLOR: blue"&gt;AddHandler &lt;/SPAN&gt;c.Orders.AssociationChanged, &lt;SPAN style="COLOR: blue"&gt;AddressOf &lt;/SPAN&gt;Orders_CollectionChanged
        &lt;SPAN style="COLOR: blue"&gt;Next
    End Sub

    Protected Overrides Sub &lt;/SPAN&gt;InsertItem(&lt;SPAN style="COLOR: blue"&gt;ByVal &lt;/SPAN&gt;index &lt;SPAN style="COLOR: blue"&gt;As Integer&lt;/SPAN&gt;, &lt;SPAN style="COLOR: blue"&gt;ByVal &lt;/SPAN&gt;item &lt;SPAN style="COLOR: blue"&gt;As &lt;/SPAN&gt;Customer)
        &lt;SPAN style="COLOR: blue"&gt;AddHandler &lt;/SPAN&gt;item.Orders.AssociationChanged, &lt;SPAN style="COLOR: blue"&gt;AddressOf &lt;/SPAN&gt;Orders_CollectionChanged

        &lt;SPAN style="COLOR: green"&gt;'Tell the ObjectContext to start tracking this customer entity
        &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.Context.AddToCustomers(item)
        &lt;SPAN style="COLOR: blue"&gt;MyBase&lt;/SPAN&gt;.InsertItem(index, item)
    &lt;SPAN style="COLOR: blue"&gt;End Sub

    Protected Overrides Sub &lt;/SPAN&gt;RemoveItem(&lt;SPAN style="COLOR: blue"&gt;ByVal &lt;/SPAN&gt;index &lt;SPAN style="COLOR: blue"&gt;As Integer&lt;/SPAN&gt;)
        &lt;SPAN style="COLOR: blue"&gt;Dim &lt;/SPAN&gt;customer = &lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;(index)
        &lt;SPAN style="COLOR: blue"&gt;RemoveHandler &lt;/SPAN&gt;customer.Orders.AssociationChanged, &lt;SPAN style="COLOR: blue"&gt;AddressOf &lt;/SPAN&gt;Orders_CollectionChanged

        &lt;SPAN style="COLOR: blue"&gt;For &lt;/SPAN&gt;i = customer.Orders.Count - 1 &lt;SPAN style="COLOR: blue"&gt;To &lt;/SPAN&gt;0 &lt;SPAN style="COLOR: blue"&gt;Step &lt;/SPAN&gt;-1
            &lt;SPAN style="COLOR: green"&gt;'When deleting a customer, delete any orders if any exist
            &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.Context.DeleteObject(customer.Orders(i))
        &lt;SPAN style="COLOR: blue"&gt;Next

        &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;'Tell the ObjectContext to delete this customer entity
        &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.Context.DeleteObject(customer)
        &lt;SPAN style="COLOR: blue"&gt;MyBase&lt;/SPAN&gt;.RemoveItem(index)
    &lt;SPAN style="COLOR: blue"&gt;End Sub

    Private Sub &lt;/SPAN&gt;Orders_CollectionChanged(&lt;SPAN style="COLOR: blue"&gt;ByVal &lt;/SPAN&gt;sender &lt;SPAN style="COLOR: blue"&gt;As Object&lt;/SPAN&gt;, _
                                         &lt;SPAN style="COLOR: blue"&gt;ByVal &lt;/SPAN&gt;e &lt;SPAN style="COLOR: blue"&gt;As &lt;/SPAN&gt;CollectionChangeEventArgs)
        &lt;SPAN style="COLOR: blue"&gt;If &lt;/SPAN&gt;e.Action = CollectionChangeAction.Remove &lt;SPAN style="COLOR: blue"&gt;Then
            &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;'Adding an order to a customer is handled automatically 
            ' for us but we need to tell the ObjectContext to delete the order
            ' if an order is removed from the Orders EntityCollection 
           &lt;STRONG&gt; &lt;/STRONG&gt;&lt;/SPAN&gt;&lt;STRONG&gt;&lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.Context.DeleteObject(&lt;SPAN style="COLOR: blue"&gt;CType&lt;/SPAN&gt;(e.Element, Order))&lt;/STRONG&gt;
        &lt;SPAN style="COLOR: blue"&gt;End If
    End Sub
End Class
&lt;/SPAN&gt;&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;&lt;STRONG&gt;Loading the Master-Detail Entities &lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Finally we’re ready to write a LINQ query to load the entities into our CustomerCollection and then set that as the Source property of the MasterViewSource. In this example I’m loading the Orders explicitly by calling .Include(“Orders”) on the LINQ query which constructs a single statement to retrieve the Customer and all their Orders from the database. &lt;A href="http://blogs.msdn.com/bethmassi/archive/2008/12/10/master-details-with-entity-framework-explicit-load.aspx" target=_blank mce_href="http://blogs.msdn.com/bethmassi/archive/2008/12/10/master-details-with-entity-framework-explicit-load.aspx"&gt;I discuss explicit load in this post&lt;/A&gt;. &lt;/P&gt;
&lt;P&gt;We can then grab a reference to the MasterViewSource &amp;amp; DetailViewSource’s View property in order to add/remove items in the collections. When we’re done, we can call SaveChanges on the ObjectContext and the database will be updated. &lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;Private &lt;/SPAN&gt;db &lt;SPAN style="COLOR: blue"&gt;As New &lt;/SPAN&gt;OMSEntities &lt;SPAN style="COLOR: green"&gt;'EF ObjectContext connects to database and tracks changes
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Private &lt;/SPAN&gt;CustomerData &lt;SPAN style="COLOR: blue"&gt;As &lt;/SPAN&gt;CustomerCollection &lt;SPAN style="COLOR: green"&gt;'inherits from ObservableCollection

&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Private &lt;/SPAN&gt;MasterViewSource &lt;SPAN style="COLOR: blue"&gt;As &lt;/SPAN&gt;CollectionViewSource
&lt;SPAN style="COLOR: blue"&gt;Private &lt;/SPAN&gt;DetailViewSource &lt;SPAN style="COLOR: blue"&gt;As &lt;/SPAN&gt;CollectionViewSource

&lt;SPAN style="COLOR: green"&gt;'provides currency to controls (position &amp;amp; movement in the collections)
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Private WithEvents &lt;/SPAN&gt;MasterView &lt;SPAN style="COLOR: blue"&gt;As &lt;/SPAN&gt;ListCollectionView
&lt;SPAN style="COLOR: blue"&gt;Private &lt;/SPAN&gt;DetailsView &lt;SPAN style="COLOR: blue"&gt;As &lt;/SPAN&gt;BindingListCollectionView

&lt;SPAN style="COLOR: blue"&gt;Private Sub &lt;/SPAN&gt;Window_Loaded() &lt;SPAN style="COLOR: blue"&gt;Handles MyBase&lt;/SPAN&gt;.Loaded

    &lt;SPAN style="COLOR: blue"&gt;Dim &lt;/SPAN&gt;query = &lt;SPAN style="COLOR: blue"&gt;From &lt;/SPAN&gt;c &lt;SPAN style="COLOR: blue"&gt;In &lt;/SPAN&gt;db.Customers.Include(&lt;SPAN style="COLOR: #a31515"&gt;"Orders"&lt;/SPAN&gt;) _
                &lt;SPAN style="COLOR: blue"&gt;Where &lt;/SPAN&gt;c.CustomerID = 1 _
                &lt;SPAN style="COLOR: blue"&gt;Select &lt;/SPAN&gt;c

    &lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.CustomerData = &lt;SPAN style="COLOR: blue"&gt;New &lt;/SPAN&gt;CustomerCollection(query, db)

    &lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.MasterViewSource = &lt;SPAN style="COLOR: blue"&gt;CType&lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.FindResource(&lt;SPAN style="COLOR: #a31515"&gt;"MasterViewSource"&lt;/SPAN&gt;), CollectionViewSource)
    &lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.DetailViewSource = &lt;SPAN style="COLOR: blue"&gt;CType&lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.FindResource(&lt;SPAN style="COLOR: #a31515"&gt;"DetailsViewSource"&lt;/SPAN&gt;), CollectionViewSource)
    &lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.MasterViewSource.Source = &lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.CustomerData

    &lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.MasterView = &lt;SPAN style="COLOR: blue"&gt;CType&lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.MasterViewSource.View, ListCollectionView)
    &lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.DetailsView = &lt;SPAN style="COLOR: blue"&gt;CType&lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.DetailViewSource.View, BindingListCollectionView)
&lt;SPAN style="COLOR: blue"&gt;End Sub&lt;/SPAN&gt;&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;Private Sub &lt;/SPAN&gt;MasterView_CurrentChanged() &lt;SPAN style="COLOR: blue"&gt;Handles &lt;/SPAN&gt;MasterView.CurrentChanged
    &lt;SPAN style="COLOR: green"&gt;'We need to grab the new child view when the master's position changes
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.DetailsView = &lt;SPAN style="COLOR: blue"&gt;CType&lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.DetailViewSource.View, BindingListCollectionView)
&lt;SPAN style="COLOR: blue"&gt;End Sub

Private Sub &lt;/SPAN&gt;btnSave_Click() &lt;SPAN style="COLOR: blue"&gt;Handles &lt;/SPAN&gt;btnSave.Click
    &lt;SPAN style="COLOR: blue"&gt;Try
        &lt;/SPAN&gt;db.SaveChanges()
        MessageBox.Show(&lt;SPAN style="COLOR: #a31515"&gt;"Customer data saved."&lt;/SPAN&gt;, &lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.Title, MessageBoxButton.OK, MessageBoxImage.Information)
    &lt;SPAN style="COLOR: blue"&gt;Catch &lt;/SPAN&gt;ex &lt;SPAN style="COLOR: blue"&gt;As &lt;/SPAN&gt;Exception
        MsgBox(ex.ToString())
    &lt;SPAN style="COLOR: blue"&gt;End Try
End Sub

Private Sub &lt;/SPAN&gt;btnDelete_Click() &lt;SPAN style="COLOR: blue"&gt;Handles &lt;/SPAN&gt;btnDelete.Click
    &lt;SPAN style="COLOR: blue"&gt;If Me&lt;/SPAN&gt;.MasterView.CurrentPosition &amp;gt; -1 &lt;SPAN style="COLOR: blue"&gt;Then
        Me&lt;/SPAN&gt;.MasterView.RemoveAt(&lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.MasterView.CurrentPosition)
    &lt;SPAN style="COLOR: blue"&gt;End If
End Sub

Private Sub &lt;/SPAN&gt;btnAdd_Click() &lt;SPAN style="COLOR: blue"&gt;Handles &lt;/SPAN&gt;btnAdd.Click
    &lt;SPAN style="COLOR: blue"&gt;Dim &lt;/SPAN&gt;customer = &lt;SPAN style="COLOR: blue"&gt;CType&lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.MasterView.AddNew, Customer)
    &lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.MasterView.CommitNew()
&lt;SPAN style="COLOR: blue"&gt;End Sub

Private Sub &lt;/SPAN&gt;btnPrevious_Click() &lt;SPAN style="COLOR: blue"&gt;Handles &lt;/SPAN&gt;btnPrevious.Click
    &lt;SPAN style="COLOR: blue"&gt;If Me&lt;/SPAN&gt;.MasterView.CurrentPosition &amp;gt; 0 &lt;SPAN style="COLOR: blue"&gt;Then
        Me&lt;/SPAN&gt;.MasterView.MoveCurrentToPrevious()
    &lt;SPAN style="COLOR: blue"&gt;End If
End Sub

Private Sub &lt;/SPAN&gt;btnNext_Click() &lt;SPAN style="COLOR: blue"&gt;Handles &lt;/SPAN&gt;btnNext.Click
    &lt;SPAN style="COLOR: blue"&gt;If Me&lt;/SPAN&gt;.MasterView.CurrentPosition &amp;lt; &lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.MasterView.Count - 1 &lt;SPAN style="COLOR: blue"&gt;Then
        Me&lt;/SPAN&gt;.MasterView.MoveCurrentToNext()
    &lt;SPAN style="COLOR: blue"&gt;End If
End Sub

Private Sub &lt;/SPAN&gt;btnAddDetail_Click() &lt;SPAN style="COLOR: blue"&gt;Handles &lt;/SPAN&gt;btnAddDetail.Click
    &lt;SPAN style="COLOR: blue"&gt;Dim &lt;/SPAN&gt;order = &lt;SPAN style="COLOR: blue"&gt;CType&lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.DetailsView.AddNew, Order)
    &lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.DetailsView.CommitNew()
&lt;SPAN style="COLOR: blue"&gt;End Sub

Private Sub &lt;/SPAN&gt;btnDeleteDetail_Click() &lt;SPAN style="COLOR: blue"&gt;Handles &lt;/SPAN&gt;btnDeleteDetail.Click
    &lt;SPAN style="COLOR: blue"&gt;If Me&lt;/SPAN&gt;.DetailsView.CurrentPosition &amp;gt; -1 &lt;SPAN style="COLOR: blue"&gt;Then
        Me&lt;/SPAN&gt;.DetailsView.RemoveAt(&lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.DetailsView.CurrentPosition)
    &lt;SPAN style="COLOR: blue"&gt;End If
End Sub&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P&gt;Now we can Add, Edit, and Delete Customer and their Orders at the same time and changes will be propagated properly to the database through Entity Framework in one call to SaveChanges. I’ve updated &lt;A href="http://code.msdn.microsoft.com/Project/Download/FileDownload.aspx?ProjectName=wpfdatavideos&amp;amp;DownloadId=6509" target=_blank mce_href="http://code.msdn.microsoft.com/Project/Download/FileDownload.aspx?ProjectName=wpfdatavideos&amp;amp;DownloadId=6509"&gt;this complete &lt;STRONG&gt;sample application&lt;/STRONG&gt;&lt;/A&gt; that demonstrates this as well as other aspects of WPF Data Binding with Entity Framework so have a look.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;UPDATE&lt;/STRONG&gt;: Milind talks about some of the tooling improvements in Visual Studio 2010 on the VSData blog regarding building WPF forms against Entity Data Models so check it out --&amp;gt;&amp;nbsp;&lt;A href="http://blogs.msdn.com/vsdata/archive/2009/05/20/wpf-data-binding-creating-a-master-details-form-in-visual-studio-2010.aspx"&gt;WPF Data Binding: Creating a Master-Details form in Visual Studio 2010&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;Enjoy!&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9833642" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Visual+Basic/default.aspx">Visual Basic</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/WPF/default.aspx">WPF</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/DevCenter/default.aspx">DevCenter</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Article/default.aspx">Article</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Data/default.aspx">Data</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Entity+Framework/default.aspx">Entity Framework</category></item><item><title>Implementing Validation in WPF on Entity Framework Entities</title><link>http://blogs.msdn.com/bethmassi/archive/2009/07/07/implementing-validation-in-wpf-on-entity-framework-entities.aspx</link><pubDate>Wed, 08 Jul 2009 03:14:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9823270</guid><dc:creator>Beth Massi</dc:creator><slash:comments>13</slash:comments><comments>http://blogs.msdn.com/bethmassi/comments/9823270.aspx</comments><wfw:commentRss>http://blogs.msdn.com/bethmassi/commentrss.aspx?PostID=9823270</wfw:commentRss><wfw:comment>http://blogs.msdn.com/bethmassi/rsscomments.aspx?PostID=9823270</wfw:comment><description>&lt;P&gt;I’ve blogged before about implementing &lt;A href="http://blogs.msdn.com/bethmassi/archive/2008/02/25/simple-validation-with-linq-to-sql-classes.aspx" target=_blank mce_href="http://blogs.msdn.com/bethmassi/archive/2008/02/25/simple-validation-with-linq-to-sql-classes.aspx"&gt;validation on LINQ to SQL classes&lt;/A&gt; as well as how to &lt;A href="http://blogs.msdn.com/bethmassi/archive/2008/06/27/displaying-data-validation-messages-in-wpf.aspx" target=_blank mce_href="http://blogs.msdn.com/bethmassi/archive/2008/06/27/displaying-data-validation-messages-in-wpf.aspx"&gt;customize the display of error messages in WPF&lt;/A&gt;. In this post I want to show how you can use these same techniques to validate entities coming from the Entity Framework (EF). Like LINQ to SQL classes, Entity Framework entities are implemented as &lt;A href="http://msdn.microsoft.com/en-us/library/yfzd5350.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/yfzd5350.aspx"&gt;partial classes&lt;/A&gt; so that you can extend them with your own code on top of the code that the designers generate for you. You can extend EF entities in a similar way as LINQ to SQL classes.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Creating the Partial Class&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Let’s take the example that I started &lt;A href="http://msdn.microsoft.com/en-us/dd776540.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/dd776540.aspx"&gt;here in this How Do I video&lt;/A&gt; on building a simple data entry form to edit customers. You can &lt;A href="http://code.msdn.microsoft.com/Project/Download/FileDownload.aspx?ProjectName=wpfdatavideos&amp;amp;DownloadId=6316" target=_blank mce_href="http://code.msdn.microsoft.com/Project/Download/FileDownload.aspx?ProjectName=wpfdatavideos&amp;amp;DownloadId=6316"&gt;download the code for that video here&lt;/A&gt;. In this sample I have two projects, one for the WPF client (WpfEfDataEntry) and one for the Data Access Layer (WpfEfDAL) that contains a simple Entity Data Model (edmx) of a little database I created that tracks customers and their orders. &lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/ImplementingValidationinWPFonEFEntities_A82B/image_2.png" mce_href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/ImplementingValidationinWPFonEFEntities_A82B/image_2.png"&gt;&lt;IMG title=image style="BORDER-TOP-WIDTH: 0px; DISPLAY: inline; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; MARGIN: 0px; BORDER-RIGHT-WIDTH: 0px" height=320 alt=image src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/ImplementingValidationinWPFonEFEntities_A82B/image_thumb.png" width=242 align=left border=0 mce_src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/ImplementingValidationinWPFonEFEntities_A82B/image_thumb.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/ImplementingValidationinWPFonEFEntities_A82B/image_10.png" mce_href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/ImplementingValidationinWPFonEFEntities_A82B/image_10.png"&gt;&lt;IMG title=image style="BORDER-TOP-WIDTH: 0px; DISPLAY: inline; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=416 alt=image src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/ImplementingValidationinWPFonEFEntities_A82B/image_thumb_4.png" width=473 border=0 mce_src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/ImplementingValidationinWPFonEFEntities_A82B/image_thumb_4.png"&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;To extend the Customer class that is generated from the EF designer, right-click on the DAL project and select Add –&amp;gt; Class then name it Customer. This places the class in the same Namespace as the entities that are generated by the designer. This is necessary for partial classes to work. (Partial classes are just a way that you can define one class in multiple physical files and Visual Studio will handle compiling them into one class for you.) &lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/ImplementingValidationinWPFonEFEntities_A82B/image_12.png" mce_href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/ImplementingValidationinWPFonEFEntities_A82B/image_12.png"&gt;&lt;IMG title=image style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; DISPLAY: inline; MARGIN: 0px 15px 0px 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" height=352 alt=image src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/ImplementingValidationinWPFonEFEntities_A82B/image_thumb_5.png" width=324 align=left border=0 mce_src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/ImplementingValidationinWPFonEFEntities_A82B/image_thumb_5.png"&gt;&lt;/A&gt; Here’s a trick in VB. You know you got your partial class in the right namespace when you drop down the Declarations dropdown and you see the list of partial methods and properties that the class defines. &lt;/P&gt;
&lt;P&gt;Also in VB the Partial keyword is only required on one of the class declarations in one of the files. (In C# it’s required on all of them.) The EF designer generates the Customer class with the partial keyword. If you click the “Show all Files” button on the Solution Explorer toolbar and then expand the .edmx you can open the .Designer file and see the entity Partial Class definitions:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;Partial Public Class &lt;/SPAN&gt;Customer    &lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;You can of course be explicit in VB and add the Partial keyword to all your partial class files as well. &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Adding Validation to the Partial Class&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;To add validation we can implement the IDataErrorInfo interface in our customer partial class. Using this interface will make validation errors display in Winforms as well as WPF so I tend to prefer this implementation over others like &lt;A href="http://msdn.microsoft.com/en-us/library/system.windows.data.binding.validationrules.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/system.windows.data.binding.validationrules.aspx"&gt;ValidationRules collection&lt;/A&gt; in WPF. For this example let’s make sure that the LastName field isn’t empty but we’ll also provide a default value by specifying it in the constructor. This code is the same code we would use if we were working with LINQ to SQL classes. &lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;Imports &lt;/SPAN&gt;System.ComponentModel

&lt;SPAN style="COLOR: blue"&gt;Partial Public Class &lt;/SPAN&gt;Customer
    &lt;SPAN style="COLOR: blue"&gt;Implements &lt;/SPAN&gt;IDataErrorInfo

&lt;SPAN style="COLOR: blue"&gt;#Region &lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;"IDataErrorInfo Members"
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Private &lt;/SPAN&gt;m_validationErrors &lt;SPAN style="COLOR: blue"&gt;As New &lt;/SPAN&gt;Dictionary(&lt;SPAN style="COLOR: blue"&gt;Of String&lt;/SPAN&gt;, &lt;SPAN style="COLOR: blue"&gt;String&lt;/SPAN&gt;)

    &lt;SPAN style="COLOR: blue"&gt;Private Sub &lt;/SPAN&gt;AddError(&lt;SPAN style="COLOR: blue"&gt;ByVal &lt;/SPAN&gt;columnName &lt;SPAN style="COLOR: blue"&gt;As String&lt;/SPAN&gt;, &lt;SPAN style="COLOR: blue"&gt;ByVal &lt;/SPAN&gt;msg &lt;SPAN style="COLOR: blue"&gt;As String&lt;/SPAN&gt;)
        &lt;SPAN style="COLOR: blue"&gt;If Not &lt;/SPAN&gt;m_validationErrors.ContainsKey(columnName) &lt;SPAN style="COLOR: blue"&gt;Then
            &lt;/SPAN&gt;m_validationErrors.Add(columnName, msg)
        &lt;SPAN style="COLOR: blue"&gt;End If
    End Sub

    Private Sub &lt;/SPAN&gt;RemoveError(&lt;SPAN style="COLOR: blue"&gt;ByVal &lt;/SPAN&gt;columnName &lt;SPAN style="COLOR: blue"&gt;As String&lt;/SPAN&gt;)
        &lt;SPAN style="COLOR: blue"&gt;If &lt;/SPAN&gt;m_validationErrors.ContainsKey(columnName) &lt;SPAN style="COLOR: blue"&gt;Then
            &lt;/SPAN&gt;m_validationErrors.Remove(columnName)
        &lt;SPAN style="COLOR: blue"&gt;End If
    End Sub

    Public ReadOnly Property &lt;/SPAN&gt;HasErrors() &lt;SPAN style="COLOR: blue"&gt;As Boolean
        Get
            Return &lt;/SPAN&gt;m_validationErrors.Count &amp;gt; 0
        &lt;SPAN style="COLOR: blue"&gt;End Get
    End Property

    Public ReadOnly Property &lt;/SPAN&gt;[Error]() &lt;SPAN style="COLOR: blue"&gt;As String _&lt;BR&gt;        Implements &lt;/SPAN&gt;System.ComponentModel.IDataErrorInfo.Error
        &lt;SPAN style="COLOR: blue"&gt;Get
            If &lt;/SPAN&gt;m_validationErrors.Count &amp;gt; 0 &lt;SPAN style="COLOR: blue"&gt;Then
                Return &lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;"Customer data is invalid"
            &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Else
                Return Nothing
            End If
        End Get
    End Property

    Default Public ReadOnly Property &lt;/SPAN&gt;Item(&lt;SPAN style="COLOR: blue"&gt;ByVal &lt;/SPAN&gt;columnName &lt;SPAN style="COLOR: blue"&gt;As String&lt;/SPAN&gt;) &lt;SPAN style="COLOR: blue"&gt;As String _&lt;BR&gt;        Implements &lt;/SPAN&gt;System.ComponentModel.IDataErrorInfo.Item
        &lt;SPAN style="COLOR: blue"&gt;Get
            If &lt;/SPAN&gt;m_validationErrors.ContainsKey(columnName) &lt;SPAN style="COLOR: blue"&gt;Then
                Return &lt;/SPAN&gt;m_validationErrors(columnName).ToString
            &lt;SPAN style="COLOR: blue"&gt;Else
                Return Nothing
            End If
        End Get
    End Property
#End Region

    Public Sub New&lt;/SPAN&gt;()
        &lt;SPAN style="COLOR: green"&gt;'Set defaults
        &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.LastName = &lt;SPAN style="COLOR: #a31515"&gt;"[new]"
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;End Sub&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Now we can write our validation code to check the LastName field. If you look back at the generated Customer class in the .Designer file, notice that there are On&lt;EM&gt;FieldName&lt;/EM&gt;Changing and On&lt;EM&gt;FieldName&lt;/EM&gt;Changed methods that are also declared as Partial. These are &lt;A href="http://msdn.microsoft.com/en-us/library/bb531348.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/bb531348.aspx"&gt;partial methods&lt;/A&gt;, a new feature introduced with Visual Studio 2008, that allow you to supply additional code that is called from the generated class. The Changing/Changed methods are called in the property setters. We’ll define the OnLastNameChanged to make sure the user enters a LastName:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: green"&gt;    ''' &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;summary&amp;gt;
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;''' This method is called in the LastName property setter of the customer
    '''  partial class generated by the Entity Data Model designer.
    ''' &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/summary&amp;gt;
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Private Sub &lt;/SPAN&gt;OnLastNameChanged()
        &lt;SPAN style="COLOR: green"&gt;'Perform validation. 
        &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;If &lt;/SPAN&gt;_LastName &lt;SPAN style="COLOR: blue"&gt;Is Nothing OrElse &lt;/SPAN&gt;_LastName.Trim() = &lt;SPAN style="COLOR: #a31515"&gt;"" &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;OrElse &lt;/SPAN&gt;_LastName.Trim() = &lt;SPAN style="COLOR: #a31515"&gt;"[new]" &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Then
            Me&lt;/SPAN&gt;.AddError(&lt;SPAN style="COLOR: #a31515"&gt;"LastName"&lt;/SPAN&gt;, &lt;SPAN style="COLOR: #a31515"&gt;"Please enter a last name."&lt;/SPAN&gt;)
        &lt;SPAN style="COLOR: blue"&gt;Else
            Me&lt;/SPAN&gt;.RemoveError(&lt;SPAN style="COLOR: #a31515"&gt;"LastName"&lt;/SPAN&gt;)
        &lt;SPAN style="COLOR: blue"&gt;End If
    End Sub

End Class
&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P&gt;Now all we need to do is specify on the binding in the XAML of the WPF form to display the validation errors.&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;TextBox &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Name&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="txtLastName" &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Width&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="Auto" &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Height&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="28" &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Margin&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="3" 
         &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Text&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="{&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Binding &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Path&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=LastName, &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;&lt;STRONG&gt;ValidatesOnDataErrors&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&lt;STRONG&gt;=True&lt;/STRONG&gt;}"/&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;This is exactly the same as we did &lt;A href="http://blogs.msdn.com/bethmassi/archive/2008/06/27/displaying-data-validation-messages-in-wpf.aspx" target=_blank mce_href="http://blogs.msdn.com/bethmassi/archive/2008/06/27/displaying-data-validation-messages-in-wpf.aspx"&gt;in this post&lt;/A&gt; when working with LINQ to SQL. Read that post to also see how to change the default error template which controls how the errors are displayed.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Adding Validation to Entity References&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;As you can see validating scalar properties on EF entities works the same as with LINQ to SQL classes. However what if we wanted to make sure that an entity reference was also specified on an EF entity? &lt;A href="http://blogs.msdn.com/bethmassi/archive/2009/05/04/notifying-the-ui-when-entity-references-change-in-lookup-comboboxes.aspx" target=_blank mce_href="http://blogs.msdn.com/bethmassi/archive/2009/05/04/notifying-the-ui-when-entity-references-change-in-lookup-comboboxes.aspx"&gt;I’ve posted before&lt;/A&gt; about how to get notified when entity references change. But what if we also want to make sure an entity reference is not empty? For instance, in the case of the Order entity above, how would we write a validation to make sure that the Customer entity reference was specified on the Order before we tried to save? &lt;/P&gt;
&lt;P&gt;Looking back up at the Customer (1)—(*) Order in the diagram above, the Order entity has a reference to its Customer parent as specified by the navigation property. In the database there is a foreign key relationship on CustomerID and that is inferred here by EF. This is a difference from LINQ to SQL classes where the classes contain the foreign keys as scalar properties as well. We can’t validate EF entities the same way because there are no scalar properties for the foreign keys. Instead we need to add an event handler to the AssociationChanged event on the entity reference (&lt;A class="" href="http://blogs.msdn.com/bethmassi/archive/2009/05/04/notifying-the-ui-when-entity-references-change-in-lookup-comboboxes.aspx" target=_blank mce_href="http://blogs.msdn.com/bethmassi/archive/2009/05/04/notifying-the-ui-when-entity-references-change-in-lookup-comboboxes.aspx"&gt;like I showed before&lt;/A&gt;) and then add in our validation. Remember that the AssociationChanged event will fire twice when we are selecting a new reference, once when the old entity reference is removed and then once when the new one is added. &lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;Imports &lt;/SPAN&gt;System.ComponentModel

&lt;SPAN style="COLOR: blue"&gt;Public Class &lt;/SPAN&gt;Order
    &lt;SPAN style="COLOR: blue"&gt;Implements &lt;/SPAN&gt;IDataErrorInfo

    &lt;SPAN style="COLOR: blue"&gt;Public Sub New&lt;/SPAN&gt;()
        &lt;SPAN style="COLOR: green"&gt;'Handle this event so that UI can be notified if the customer is changed
        &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;AddHandler Me&lt;/SPAN&gt;.CustomerReference.AssociationChanged, &lt;SPAN style="COLOR: blue"&gt;AddressOf &lt;/SPAN&gt;Customer_AssociationChanged

        &lt;SPAN style="COLOR: green"&gt;'Set defaults
        &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.OrderDate = &lt;SPAN style="COLOR: blue"&gt;Date&lt;/SPAN&gt;.Today()
        &lt;SPAN style="COLOR: green"&gt;'Customer is required &lt;/SPAN&gt;&lt;BR&gt;        &lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.AddError(&lt;SPAN style="COLOR: #a31515"&gt;"Customer"&lt;/SPAN&gt;, &lt;SPAN style="COLOR: #a31515"&gt;"Please select a customer."&lt;/SPAN&gt;)
    &lt;SPAN style="COLOR: blue"&gt;End Sub

    Private Sub &lt;/SPAN&gt;Customer_AssociationChanged(&lt;SPAN style="COLOR: blue"&gt;ByVal &lt;/SPAN&gt;sender &lt;SPAN style="COLOR: blue"&gt;As Object&lt;/SPAN&gt;, _
                                            &lt;SPAN style="COLOR: blue"&gt;ByVal &lt;/SPAN&gt;e &lt;SPAN style="COLOR: blue"&gt;As &lt;/SPAN&gt;CollectionChangeEventArgs)
        &lt;SPAN style="COLOR: blue"&gt;If &lt;/SPAN&gt;e.Action = CollectionChangeAction.Remove &lt;SPAN style="COLOR: blue"&gt;Then
            &lt;/SPAN&gt;OnPropertyChanging(&lt;SPAN style="COLOR: #a31515"&gt;"Customer"&lt;/SPAN&gt;)
        &lt;SPAN style="COLOR: blue"&gt;Else
            If &lt;/SPAN&gt;e.Action = CollectionChangeAction.Add &lt;SPAN style="COLOR: blue"&gt;Then
                Me&lt;/SPAN&gt;.RemoveError(&lt;SPAN style="COLOR: #a31515"&gt;"Customer"&lt;/SPAN&gt;)
            &lt;SPAN style="COLOR: blue"&gt;End If
            &lt;/SPAN&gt;OnPropertyChanged(&lt;SPAN style="COLOR: #a31515"&gt;"Customer"&lt;/SPAN&gt;)
        &lt;SPAN style="COLOR: blue"&gt;End If
    End Sub&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/ImplementingValidationinWPFonEFEntities_A82B/image_16.png" mce_href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/ImplementingValidationinWPFonEFEntities_A82B/image_16.png"&gt;&lt;IMG title=image style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; DISPLAY: inline; MARGIN: 0px 15px 0px 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" height=153 alt=image src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/ImplementingValidationinWPFonEFEntities_A82B/image_thumb_7.png" width=223 align=left border=0 mce_src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/ImplementingValidationinWPFonEFEntities_A82B/image_thumb_7.png"&gt;&lt;/A&gt;What I’m doing is putting the Order in an immediate error state so that the user can see that a Customer must be selected on the Order before it is valid. The error will only go away once they select a Customer.&lt;/P&gt;
&lt;P&gt;I’ve created a &lt;STRONG&gt;&lt;A href="http://code.msdn.microsoft.com/Project/Download/FileDownload.aspx?ProjectName=wpfdatavideos&amp;amp;DownloadId=6509" target=_blank mce_href="http://code.msdn.microsoft.com/Project/Download/FileDownload.aspx?ProjectName=wpfdatavideos&amp;amp;DownloadId=6509"&gt;sample application that you can download from Code Gallery&lt;/A&gt;&lt;/STRONG&gt;&lt;STRONG&gt;&lt;/STRONG&gt; that demonstrates using EF with WPF in a variety of ways including this example so have a look. Also make sure you check out these &lt;A href="http://msdn.microsoft.com/en-us/vbasic/bb466226.aspx#wpfentity" target=_blank mce_href="http://msdn.microsoft.com/en-us/vbasic/bb466226.aspx#wpfentity"&gt;How Do I videos on EF and WPF&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;Enjoy!&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9823270" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Visual+Basic/default.aspx">Visual Basic</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/WPF/default.aspx">WPF</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/VS2008/default.aspx">VS2008</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/DevCenter/default.aspx">DevCenter</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Article/default.aspx">Article</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Entity+Framework/default.aspx">Entity Framework</category></item><item><title>New “How Do I” Video Series Released</title><link>http://blogs.msdn.com/bethmassi/archive/2009/07/01/new-how-do-i-video-series-released.aspx</link><pubDate>Thu, 02 Jul 2009 03:28:50 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9812376</guid><dc:creator>Beth Massi</dc:creator><slash:comments>7</slash:comments><comments>http://blogs.msdn.com/bethmassi/comments/9812376.aspx</comments><wfw:commentRss>http://blogs.msdn.com/bethmassi/commentrss.aspx?PostID=9812376</wfw:commentRss><wfw:comment>http://blogs.msdn.com/bethmassi/rsscomments.aspx?PostID=9812376</wfw:comment><description>&lt;p&gt;I just released 3 new videos onto the &lt;a href="http://msdn.microsoft.com/en-us/vbasic/bb466226.aspx#wpfentity" target="_blank"&gt;VB Dev Center&lt;/a&gt; starting a new series on how to do WPF data binding with Entity Framework using &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=FBEE1648-7106-44A7-9649-6D9F6D58056E&amp;amp;displaylang=en" target="_blank"&gt;Visual Studio 2008 Service Pack 1&lt;/a&gt;. This is a “no frills” WPF series that focuses on data so you won’t see any other tools used besides Visual Studio 2008 SP1 and no flashy animations. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/vbasic/dd776537.aspx"&gt;#1 | How Do I: Get Started with Entity Framework in WPF Applications?&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/vbasic/dd776540.aspx"&gt;#2 | How Do I: Build a WPF Data Entry Form Using Entity Framework?&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/vbasic/dd776544.aspx"&gt;#3 | How Do I: Create a WPF Lookup Combobox using Entity Framework?&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The videos are a bit longer than your normal 5-minute “How Do I” videos but I tried to keep them short by re-using the data access layer I build in the first one. I hope this doesn’t confuse people. Believe me when I say this will get a lot better, &lt;a href="http://blogs.msdn.com/vsdata/archive/tags/WPF/default.aspx" target="_blank"&gt;especially tooling-wise&lt;/a&gt;, in Visual Studio 2010. But this is a good introduction to building WPF data apps against Entity Framework with the version of Visual Studio that is available now! :-) &lt;/p&gt;  &lt;p&gt;Enjoy!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9812376" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Visual+Basic/default.aspx">Visual Basic</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/WPF/default.aspx">WPF</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Videos/default.aspx">Videos</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/DevCenter/default.aspx">DevCenter</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Entity+Framework/default.aspx">Entity Framework</category></item><item><title>WPF Data Binding Samples on Code Gallery</title><link>http://blogs.msdn.com/bethmassi/archive/2009/06/17/wpf-data-binding-samples-on-code-gallery.aspx</link><pubDate>Wed, 17 Jun 2009 22:41:28 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9770286</guid><dc:creator>Beth Massi</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/bethmassi/comments/9770286.aspx</comments><wfw:commentRss>http://blogs.msdn.com/bethmassi/commentrss.aspx?PostID=9770286</wfw:commentRss><wfw:comment>http://blogs.msdn.com/bethmassi/rsscomments.aspx?PostID=9770286</wfw:comment><description>&lt;p&gt;One of the many &lt;a href="http://msdn.microsoft.com/en-us/vstudio/dd238515.aspx" target="_blank"&gt;samples released for Visual Studio 2010 Beta 1&lt;/a&gt; that you should be aware of are examples of WPF data binding against Entity Data Models. You can find some easy to follow samples here: &lt;a href="http://code.msdn.microsoft.com/WPFDatabinding"&gt;&lt;strong&gt;http://code.msdn.microsoft.com/WPFDatabinding&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This sample demonstrates how to create a WPF Forms solution that checks user input with validation code, demonstrates common controls such as DataGrid and ComboBox, and shows typical data manipulation including create, read, update, and delete. The sample solution is available in both Visual Basic and C# and is intended for use with Visual Studio 2010 Beta 1 and with the .NET Framework 3.5.&amp;#160; In the future, we will release a sample that performs with the .Net Framework 4.0 Beta.&lt;/p&gt;  &lt;p&gt;Check out the &lt;a href="http://blogs.msdn.com/vsdata" target="_blank"&gt;VS Data Team blog&lt;/a&gt; for more information on WPF data-binding and Karl’s blog on a great &lt;a href="http://karlshifflett.wordpress.com/2009/06/10/wpf-sample-series-listbox-grouping-sorting-subtotals-and-collapsible-regions/" target="_blank"&gt;WPF sample series&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Enjoy!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9770286" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/bethmassi/archive/tags/WPF/default.aspx">WPF</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/DevCenter/default.aspx">DevCenter</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Data/default.aspx">Data</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Entity+Framework/default.aspx">Entity Framework</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/VS2010/default.aspx">VS2010</category></item><item><title>Using the WPF ObservableCollection with EF Entities</title><link>http://blogs.msdn.com/bethmassi/archive/2009/05/08/using-the-wpf-observablecollection-with-ef-entities.aspx</link><pubDate>Sat, 09 May 2009 01:29:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9597952</guid><dc:creator>Beth Massi</dc:creator><slash:comments>12</slash:comments><comments>http://blogs.msdn.com/bethmassi/comments/9597952.aspx</comments><wfw:commentRss>http://blogs.msdn.com/bethmassi/commentrss.aspx?PostID=9597952</wfw:commentRss><wfw:comment>http://blogs.msdn.com/bethmassi/rsscomments.aspx?PostID=9597952</wfw:comment><description>&lt;P&gt;The &lt;A href="http://msdn.microsoft.com/en-us/library/ms668604.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/ms668604.aspx"&gt;ObservableCollection&lt;/A&gt; is a special WPF collection that provides proper notifications to the UI when items are added, removed, or the list is refreshed because it implements &lt;A href="http://msdn.microsoft.com/en-us/library/system.collections.specialized.inotifycollectionchanged.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.collections.specialized.inotifycollectionchanged.aspx"&gt;INotifyCollectionChanged&lt;/A&gt;. It’s common to use this collection (or inherit from it) to contain your business objects you want to bind to in WPF.&amp;nbsp; &lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;Class &lt;/SPAN&gt;Window1&lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;    Private &lt;/SPAN&gt;CustomerData &lt;SPAN style="COLOR: blue"&gt;As &lt;/SPAN&gt;ObservableCollection(&lt;SPAN style="COLOR: blue"&gt;Of &lt;/SPAN&gt;Customer)&lt;/PRE&gt;
&lt;P&gt;You can then set up a &lt;A href="http://msdn.microsoft.com/en-us/library/system.windows.data.collectionviewsource.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/system.windows.data.collectionviewsource.aspx"&gt;CollectionViewSource&lt;/A&gt; and use it’s View property to get a reference to the &lt;A href="http://msdn.microsoft.com/en-us/library/system.windows.data.listcollectionview.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/system.windows.data.listcollectionview.aspx"&gt;ListCollectionView&lt;/A&gt; in order to add and remove items instead of working with the source collection directly. This decouples your data source (and therefore any collection logic) from the form itself making it much easier to change sources later. I’ve showed &lt;A href="http://blogs.msdn.com/bethmassi/archive/2008/11/07/loading-data-and-binding-controls-in-wpf-with-collectionviewsource.aspx" target=_blank mce_href="http://blogs.msdn.com/bethmassi/archive/2008/11/07/loading-data-and-binding-controls-in-wpf-with-collectionviewsource.aspx"&gt;how to use CollectionViewSources before&lt;/A&gt; but basically you just declare them in the Window.Resources section and bind to them in XAML: &lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Window &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;x&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;:&lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Class&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="Window1"
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;xmlns&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;xmlns&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;:&lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;x&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="http://schemas.microsoft.com/winfx/2006/xaml"
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Title&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="Window1" &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Height&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="282" &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Width&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="440" &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Name&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="Window1"&amp;gt;
    &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Window.Resources&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;
      &lt;STRONG&gt;  &amp;lt;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;STRONG&gt;&lt;SPAN style="COLOR: #a31515"&gt;CollectionViewSource &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;x&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;:&lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Key&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN style="COLOR: blue"&gt;&lt;STRONG&gt;="CustomerSource" /&amp;gt;&lt;/STRONG&gt;
    &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Window.Resources&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;
    &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Grid &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;DataContext&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="{&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Binding &lt;/SPAN&gt;&lt;STRONG&gt;&lt;SPAN style="COLOR: red"&gt;Source&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;={&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;StaticResource &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;CustomerSource&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN style="COLOR: blue"&gt;&lt;STRONG&gt;}&lt;/STRONG&gt;}"&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;And then you can set the Source property in code to your collection and obtain the ListCollectionView. &lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;Dim &lt;/SPAN&gt;customerSource = &lt;SPAN style="COLOR: blue"&gt;CType&lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.Resources(&lt;SPAN style="COLOR: #a31515"&gt;"CustomerSource"&lt;/SPAN&gt;), CollectionViewSource)
customerSource.&lt;STRONG&gt;Source&lt;/STRONG&gt; = &lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.CustomerData

&lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.View = &lt;SPAN style="COLOR: blue"&gt;CType&lt;/SPAN&gt;(customerSource.&lt;STRONG&gt;View&lt;/STRONG&gt;, ListCollectionView)&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;Then you use the View to add and remove items from the collection and the UI will update properly: &lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;Private Sub &lt;/SPAN&gt;btnDelete_Click() &lt;SPAN style="COLOR: blue"&gt;Handles &lt;/SPAN&gt;btnDelete.Click
       &lt;SPAN style="COLOR: blue"&gt;If Me&lt;/SPAN&gt;.View.CurrentPosition &amp;gt; -1 &lt;SPAN style="COLOR: blue"&gt;Then
           &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;'removes the currently selected customer from the underlying collection 
           &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.View.RemoveAt(&lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.View.CurrentPosition)
       &lt;SPAN style="COLOR: blue"&gt;End If
   End Sub

   Private Sub &lt;/SPAN&gt;btnAdd_Click() &lt;SPAN style="COLOR: blue"&gt;Handles &lt;/SPAN&gt;btnAdd.Click
       &lt;SPAN style="COLOR: green"&gt;'adds a new customer to the underlying collection 
       &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Dim &lt;/SPAN&gt;customer = &lt;SPAN style="COLOR: blue"&gt;CType&lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.View.AddNew, Customer)
       &lt;SPAN style="COLOR: green"&gt;'do something with customer if needed...
       &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.View.CommitNew()
   &lt;SPAN style="COLOR: blue"&gt;End Sub&lt;/SPAN&gt;&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;Calling these methods on the ListCollectionView will execute the &lt;A href="http://msdn.microsoft.com/en-us/library/ms654928.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/ms654928.aspx"&gt;InsertItem&lt;/A&gt; and &lt;A href="http://msdn.microsoft.com/en-us/library/ms654938.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/ms654938.aspx"&gt;RemoveItem&lt;/A&gt; methods on the ObservableCollection.&lt;/P&gt;
&lt;P&gt;Now if you are using an &lt;A href="http://msdn.microsoft.com/en-us/library/bb387122.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/bb387122.aspx"&gt;Entity Data Model (EDM)&lt;/A&gt; the designer in Visual Studio 2008 SP1 will generate entity classes for you that you can also bind to in your UI. Access to these entities is done through the &lt;A href="http://msdn.microsoft.com/en-us/library/system.data.objects.objectcontext.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/system.data.objects.objectcontext.aspx"&gt;ObjectContext&lt;/A&gt; and the designer also creates a class for you that inherits from this when you create the EDM. It is named something like xxxEntites. (For instance, in Visual Studio 2008 SP1 “Add New Item” and select ADO.NET Entity Data Model and name it Northwind.edmx. Generate from Database and select Northwind. Select all the tables and then the designer will generate an ObjectContext called NorthwindEntities and entity classes based on the tables in the database.)&lt;/P&gt;
&lt;P&gt;Because the ObjectContext is what tracks changes on entities you can place entities inside an ObservableCollection but in order for the ObjectContext to be notified that adds and deletes need to be tracked you need to write a bit of code. The easiest thing to do is to create your own class that inherits from ObservableCollection and override the InsertItem and RemoveItem methods so that you can tell the ObjectContext to either add or delete the entity which will ultimately execute against the database. In the constructor pass a reference to the ObjectContext. You can also pass in any collection of entities, say from a LINQ query, and then add them to the ObservableCollection. For example:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;Imports &lt;/SPAN&gt;NorthwindDAL
&lt;SPAN style="COLOR: blue"&gt;Imports &lt;/SPAN&gt;System.Collections.ObjectModel

&lt;SPAN style="COLOR: blue"&gt;Public Class &lt;/SPAN&gt;CustomerCollection
    &lt;SPAN style="COLOR: blue"&gt;Inherits &lt;/SPAN&gt;ObservableCollection(&lt;SPAN style="COLOR: blue"&gt;Of &lt;/SPAN&gt;Customer)

   &lt;SPAN style="COLOR: blue"&gt; Private &lt;/SPAN&gt;_context &lt;SPAN style="COLOR: blue"&gt;As &lt;/SPAN&gt;NorthwindEntities
    &lt;SPAN style="COLOR: blue"&gt;Public ReadOnly Property &lt;/SPAN&gt;Context() &lt;SPAN style="COLOR: blue"&gt;As &lt;/SPAN&gt;NorthwindEntities
        &lt;SPAN style="COLOR: blue"&gt;Get
            Return &lt;/SPAN&gt;_context
        &lt;SPAN style="COLOR: blue"&gt;End Get
    End Property

    Sub New&lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;ByVal &lt;/SPAN&gt;customers &lt;SPAN style="COLOR: blue"&gt;As &lt;/SPAN&gt;IEnumerable(&lt;SPAN style="COLOR: blue"&gt;Of &lt;/SPAN&gt;Customer), &lt;SPAN style="COLOR: blue"&gt;ByVal &lt;/SPAN&gt;context &lt;SPAN style="COLOR: blue"&gt;As &lt;/SPAN&gt;NorthwindEntities)
        &lt;SPAN style="COLOR: blue"&gt;MyBase&lt;/SPAN&gt;.New(customers)&lt;BR&gt;       &lt;SPAN style="COLOR: blue"&gt; &lt;/SPAN&gt;_context = context
    &lt;SPAN style="COLOR: blue"&gt;End Sub

    Protected Overrides Sub &lt;/SPAN&gt;InsertItem(&lt;SPAN style="COLOR: blue"&gt;ByVal &lt;/SPAN&gt;index &lt;SPAN style="COLOR: blue"&gt;As Integer&lt;/SPAN&gt;, &lt;SPAN style="COLOR: blue"&gt;ByVal &lt;/SPAN&gt;item &lt;SPAN style="COLOR: blue"&gt;As &lt;/SPAN&gt;Customer)
   &lt;SPAN style="COLOR: blue"&gt;     Me&lt;/SPAN&gt;.Context.AddToCustomers(item)
   &lt;SPAN style="COLOR: blue"&gt;     MyBase&lt;/SPAN&gt;.InsertItem(index, item)
    &lt;SPAN style="COLOR: blue"&gt;End Sub

    Protected Overrides Sub &lt;/SPAN&gt;RemoveItem(&lt;SPAN style="COLOR: blue"&gt;ByVal &lt;/SPAN&gt;index &lt;SPAN style="COLOR: blue"&gt;As Integer&lt;/SPAN&gt;)
        &lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.Context.DeleteObject(&lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;(index))
        &lt;SPAN style="COLOR: blue"&gt;MyBase&lt;/SPAN&gt;.RemoveItem(index)
    &lt;SPAN style="COLOR: blue"&gt;End Sub

End Class&lt;/SPAN&gt;&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;Then you can use the collection on your WPF form instead like so:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;Imports &lt;/SPAN&gt;NorthwindDAL

&lt;SPAN style="COLOR: blue"&gt;Class &lt;/SPAN&gt;Window1
    &lt;SPAN style="COLOR: blue"&gt;Private &lt;/SPAN&gt;db &lt;SPAN style="COLOR: blue"&gt;As New &lt;/SPAN&gt;NorthwindEntities
    &lt;SPAN style="COLOR: blue"&gt;Private &lt;/SPAN&gt;CustomerData &lt;SPAN style="COLOR: blue"&gt;As &lt;/SPAN&gt;CustomerCollection
    &lt;SPAN style="COLOR: blue"&gt;Private &lt;/SPAN&gt;View &lt;SPAN style="COLOR: blue"&gt;As &lt;/SPAN&gt;ListCollectionView

    &lt;SPAN style="COLOR: blue"&gt;Private Sub &lt;/SPAN&gt;Window1_Loaded() &lt;SPAN style="COLOR: blue"&gt;Handles MyBase&lt;/SPAN&gt;.Loaded

        &lt;SPAN style="COLOR: blue"&gt;Dim &lt;/SPAN&gt;results = &lt;SPAN style="COLOR: blue"&gt;From &lt;/SPAN&gt;c &lt;SPAN style="COLOR: blue"&gt;In &lt;/SPAN&gt;db.Customers _
                      &lt;SPAN style="COLOR: blue"&gt;Where &lt;/SPAN&gt;c.City.ToLower = &lt;SPAN style="COLOR: #a31515"&gt;"seattle" &lt;/SPAN&gt;_
                      &lt;SPAN style="COLOR: blue"&gt;Order By &lt;/SPAN&gt;c.LastName, c.FirstName _
                      &lt;SPAN style="COLOR: blue"&gt;Select &lt;/SPAN&gt;c

&lt;STRONG&gt;        &lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.CustomerData = &lt;SPAN style="COLOR: blue"&gt;New &lt;/SPAN&gt;CustomerCollection(results, db)&lt;/STRONG&gt;&lt;/PRE&gt;&lt;PRE class=code&gt;        &lt;SPAN style="COLOR: blue"&gt;Dim &lt;/SPAN&gt;customerSource = &lt;SPAN style="COLOR: blue"&gt;CType&lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.Resources(&lt;SPAN style="COLOR: #a31515"&gt;"CustomerSource"&lt;/SPAN&gt;), CollectionViewSource)
        customerSource.Source = &lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.CustomerData
        &lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.View = &lt;SPAN style="COLOR: blue"&gt;CType&lt;/SPAN&gt;(customerSource.View, ListCollectionView)
    &lt;SPAN style="COLOR: blue"&gt;End Sub&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class=code&gt;    &lt;SPAN style="COLOR: blue"&gt;Private Sub &lt;/SPAN&gt;btnSave_Click() &lt;SPAN style="COLOR: blue"&gt;Handles &lt;/SPAN&gt;btnSave.Click
        &lt;SPAN style="COLOR: blue"&gt;Try
            &lt;/SPAN&gt;db.SaveChanges()
            MsgBox(&lt;SPAN style="COLOR: #a31515"&gt;"Customer data was saved."&lt;/SPAN&gt;)
        &lt;SPAN style="COLOR: blue"&gt;Catch &lt;/SPAN&gt;ex &lt;SPAN style="COLOR: blue"&gt;As &lt;/SPAN&gt;Exception
            MsgBox(ex.ToString())
        &lt;SPAN style="COLOR: blue"&gt;End Try
    End Sub&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;    Private Sub &lt;/SPAN&gt;btnDelete_Click() &lt;SPAN style="COLOR: blue"&gt;Handles &lt;/SPAN&gt;btnDelete.Click
        &lt;SPAN style="COLOR: blue"&gt;If Me&lt;/SPAN&gt;.View.CurrentPosition &amp;gt; -1 &lt;SPAN style="COLOR: blue"&gt;Then
&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;            &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.View.RemoveAt(&lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.View.CurrentPosition)
        &lt;SPAN style="COLOR: blue"&gt;End If
    End Sub

    Private Sub &lt;/SPAN&gt;btnAdd_Click() &lt;SPAN style="COLOR: blue"&gt;Handles &lt;/SPAN&gt;btnAdd.Click
&lt;SPAN style="COLOR: blue"&gt;        Dim &lt;/SPAN&gt;customer = &lt;SPAN style="COLOR: blue"&gt;CType&lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.View.AddNew, Customer)
        &lt;SPAN style="COLOR: green"&gt;'do something with customer if needed...
        &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.View.CommitNew()
    &lt;SPAN style="COLOR: blue"&gt;End Sub&lt;/SPAN&gt;&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;End Class&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P&gt;Now any updates, adds or deletes you make in the UI will be propagated to the database through the Entity Framework.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Enjoy!&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9597952" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Visual+Basic/default.aspx">Visual Basic</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/WPF/default.aspx">WPF</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/LINQ/default.aspx">LINQ</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/VS2008/default.aspx">VS2008</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/DevCenter/default.aspx">DevCenter</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Article/default.aspx">Article</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Data/default.aspx">Data</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Entity+Framework/default.aspx">Entity Framework</category></item><item><title>Notifying the UI when Entity References Change in Lookup Comboboxes</title><link>http://blogs.msdn.com/bethmassi/archive/2009/05/04/notifying-the-ui-when-entity-references-change-in-lookup-comboboxes.aspx</link><pubDate>Tue, 05 May 2009 05:51:20 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9587373</guid><dc:creator>Beth Massi</dc:creator><slash:comments>6</slash:comments><comments>http://blogs.msdn.com/bethmassi/comments/9587373.aspx</comments><wfw:commentRss>http://blogs.msdn.com/bethmassi/commentrss.aspx?PostID=9587373</wfw:commentRss><wfw:comment>http://blogs.msdn.com/bethmassi/rsscomments.aspx?PostID=9587373</wfw:comment><description>&lt;p&gt;Last week &lt;a href="http://blogs.msdn.com/bethmassi/archive/2009/04/30/data-binding-wpf-lookup-combobox-values-to-ef-entities.aspx" target="_blank"&gt;I wrote about how to data bind WPF lookup comboboxes to entities&lt;/a&gt; returned from the Entity Framework. I described that the key to this type of binding is setting the SelectedItem to the object reference itself on the navigation property instead of setting SelectedValue and SelectedValuePath as in the case when you have foreign key scalar properties like LINQ to SQL classes or DataTables.&lt;/p&gt;  &lt;p&gt;However, depending on your UI, you may need a notification to fire when the entity reference changes. By default this doesn’t happen with entities generated by the &lt;a href="http://msdn.microsoft.com/en-us/library/bb738482.aspx" target="_blank"&gt;EF designer&lt;/a&gt;. Only scalar properties raise change notifications. For instance, going back to our Customer (1)—(*) Order example, the Order entity has a reference to its Customer parent as specified by the navigation property:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/DataBindingWPFLookupComboboxValuestoEFEn_F345/image_6.png" /&gt; &lt;/p&gt;  &lt;p&gt;In the database there is a foreign key relationship on CustomerID and that is inferred here by EF. If you look at the Order class that is generated you will see only change notifications raised on the scalar properties, not the navigation properties. For instance, if we take a look at a scalar property that is generated you will see the change notification partial methods generated as well:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;Partial Public Class &lt;/span&gt;Order
    &lt;span style="color: blue"&gt;Inherits Global&lt;/span&gt;.System.Data.Objects.DataClasses.EntityObject&lt;br /&gt;.&lt;br /&gt;.&lt;br /&gt;.
    &lt;span style="color: blue"&gt;Public Property &lt;/span&gt;OrderID() &lt;span style="color: blue"&gt;As Integer
        Get
            Return Me&lt;/span&gt;._OrderID
        &lt;span style="color: blue"&gt;End Get
        Set
            Me&lt;/span&gt;.OnOrderIDChanging(value)
            &lt;span style="color: blue"&gt;Me&lt;/span&gt;.ReportPropertyChanging(&lt;span style="color: #a31515"&gt;&amp;quot;OrderID&amp;quot;&lt;/span&gt;)
            &lt;span style="color: blue"&gt;Me&lt;/span&gt;._OrderID = StructuralObject.SetValidValue(value)
            &lt;span style="color: blue"&gt;Me&lt;/span&gt;.ReportPropertyChanged(&lt;span style="color: #a31515"&gt;&amp;quot;OrderID&amp;quot;&lt;/span&gt;)
            &lt;span style="color: blue"&gt;Me&lt;/span&gt;.OnOrderIDChanged
        &lt;span style="color: blue"&gt;End Set
    End Property
    Private &lt;/span&gt;_OrderID &lt;span style="color: blue"&gt;As Integer
    &lt;br /&gt;    Partial Private Sub &lt;/span&gt;OnOrderIDChanging(&lt;span style="color: blue"&gt;ByVal &lt;/span&gt;value &lt;span style="color: blue"&gt;As Integer&lt;/span&gt;)
    &lt;span style="color: blue"&gt;End Sub
    &lt;br /&gt;    Partial Private Sub &lt;/span&gt;OnOrderIDChanged()
    &lt;span style="color: blue"&gt;End Sub
&lt;/span&gt;&lt;br /&gt;.&lt;br /&gt;.&lt;br /&gt;.&lt;/pre&gt;

&lt;p&gt;EF entities that are generated by the designer inherit from &lt;a href="http://msdn.microsoft.com/en-us/library/system.data.objects.dataclasses.entityobject.aspx" target="_blank"&gt;EntityObject&lt;/a&gt; that in turn inherits from &lt;a href="http://msdn.microsoft.com/en-us/library/system.data.objects.dataclasses.structuralobject.aspx" target="_blank"&gt;StructuralObject&lt;/a&gt; that implements&amp;#160; &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged.aspx" target="_blank"&gt;INotifyPropertyChanged&lt;/a&gt;. This interface is necessary for notifying the UI (WPF and Winforms) that data bound controls should refresh their value. So say you programmatically change a scalar property then any controls bound to that property will be refreshed with the new value automatically. Or in many cases you have a UI with multiple controls bound to the same property. If the user makes a change to one control, the rest update automatically. &lt;/p&gt;

&lt;p&gt;However this notification isn’t generated on entity references. Which means that if you have a lookup combobox set up &lt;a href="http://blogs.msdn.com/bethmassi/archive/2009/04/30/data-binding-wpf-lookup-combobox-values-to-ef-entities.aspx" target="_blank"&gt;like I described in last week’s post&lt;/a&gt; and also have another control bound to the same Customer navigation property, then it won’t refresh properly. &lt;/p&gt;

&lt;p&gt;For instance, say we have an Order form with a combobox &lt;a href="http://blogs.msdn.com/bethmassi/archive/2009/04/30/data-binding-wpf-lookup-combobox-values-to-ef-entities.aspx" target="_blank"&gt;set up like before&lt;/a&gt;, where the SelectedItem is bound to the Customer property (SelectedItem=&amp;quot;{Binding Path=Customer}&amp;quot;), but we also have a listbox that shows OrderDate, Customer.LastName, Customer.FirstName:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/NotifyingtheUIwhenEntityReferencesChange_1085D/image_2.png"&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="302" alt="image" src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/NotifyingtheUIwhenEntityReferencesChange_1085D/image_thumb.png" width="468" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;ListBox &lt;/span&gt;&lt;span style="color: red"&gt;Grid.Row&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;1&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Name&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;ListBox1&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;ItemsSource&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color: #a31515"&gt;Binding&lt;/span&gt;&lt;span style="color: blue"&gt;}&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;IsSynchronizedWithCurrentItem&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;True&amp;quot;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;ItemsControl.ItemTemplate&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;DataTemplate&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;StackPanel &lt;/span&gt;&lt;span style="color: red"&gt;Orientation&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Horizontal&amp;quot;&amp;gt;
            &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;TextBlock &lt;/span&gt;&lt;span style="color: red"&gt;Width&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;60&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Text&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color: #a31515"&gt;Binding &lt;/span&gt;&lt;span style="color: red"&gt;Path&lt;/span&gt;&lt;span style="color: blue"&gt;=OrderDate, &lt;/span&gt;&lt;span style="color: red"&gt;StringFormat&lt;/span&gt;&lt;span style="color: blue"&gt;='d'}&amp;quot; /&amp;gt;
            &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;TextBlock &lt;/span&gt;&lt;span style="color: red"&gt;Text&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color: #a31515"&gt;Binding &lt;/span&gt;&lt;span style="color: red"&gt;Path&lt;/span&gt;&lt;span style="color: blue"&gt;=Customer.LastName}&amp;quot; /&amp;gt;
            &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;TextBlock &lt;/span&gt;&lt;span style="color: red"&gt;Width&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;5&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;, &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;TextBlock&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
            &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;TextBlock &lt;/span&gt;&lt;span style="color: red"&gt;Text&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color: #a31515"&gt;Binding &lt;/span&gt;&lt;span style="color: red"&gt;Path&lt;/span&gt;&lt;span style="color: blue"&gt;=Customer.FirstName}&amp;quot; /&amp;gt;
        &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;StackPanel&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;DataTemplate&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;ItemsControl.ItemTemplate&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;If the user changes the OrderDate then that change will automatically be reflected in the listbox. But if the user changes the Customer in the dropdown combobox then it will NOT update the listbox because a change notification is not raised on Customer. What’s also interesting is if you look at that part of the generated Order entity then you will actually see &lt;strong&gt;two&lt;/strong&gt; properties, one we expect called Customer and one called CustomerReference:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;.&lt;br /&gt;.&lt;br /&gt;.&lt;br /&gt;Public Property &lt;/span&gt;Customer() &lt;span style="color: blue"&gt;As &lt;/span&gt;Customer
    &lt;span style="color: blue"&gt;Get
        Return CType&lt;/span&gt;(&lt;span style="color: blue"&gt;Me&lt;/span&gt;, IEntityWithRelationships).RelationshipManager. _
        GetRelatedReference(&lt;span style="color: blue"&gt;Of &lt;/span&gt;Customer)(&lt;span style="color: #a31515"&gt;&amp;quot;OMSModel.FK_Orders_Customer&amp;quot;&lt;/span&gt;, &lt;span style="color: #a31515"&gt;&amp;quot;Customer&amp;quot;&lt;/span&gt;).Value
    &lt;span style="color: blue"&gt;End Get
    Set&lt;/span&gt;(&lt;span style="color: blue"&gt;ByVal &lt;/span&gt;value &lt;span style="color: blue"&gt;As &lt;/span&gt;Customer)
        &lt;span style="color: blue"&gt;CType&lt;/span&gt;(&lt;span style="color: blue"&gt;Me&lt;/span&gt;, IEntityWithRelationships).RelationshipManager. _
        GetRelatedReference(&lt;span style="color: blue"&gt;Of &lt;/span&gt;Customer)(&lt;span style="color: #a31515"&gt;&amp;quot;OMSModel.FK_Orders_Customer&amp;quot;&lt;/span&gt;, &lt;span style="color: #a31515"&gt;&amp;quot;Customer&amp;quot;&lt;/span&gt;).Value = value
    &lt;span style="color: blue"&gt;End Set
End Property&lt;br /&gt;.&lt;br /&gt;.&lt;br /&gt;.
Public Property &lt;/span&gt;CustomerReference() &lt;span style="color: blue"&gt;As &lt;/span&gt;EntityReference(&lt;span style="color: blue"&gt;Of &lt;/span&gt;Customer)
    &lt;span style="color: blue"&gt;Get
        Return CType&lt;/span&gt;(&lt;span style="color: blue"&gt;Me&lt;/span&gt;, IEntityWithRelationships).RelationshipManager. _
        GetRelatedReference(&lt;span style="color: blue"&gt;Of &lt;/span&gt;Customer)(&lt;span style="color: #a31515"&gt;&amp;quot;OMSModel.FK_Orders_Customer&amp;quot;&lt;/span&gt;, &lt;span style="color: #a31515"&gt;&amp;quot;Customer&amp;quot;&lt;/span&gt;)
    &lt;span style="color: blue"&gt;End Get
    Set&lt;/span&gt;(&lt;span style="color: blue"&gt;ByVal &lt;/span&gt;value &lt;span style="color: blue"&gt;As &lt;/span&gt;EntityReference(&lt;span style="color: blue"&gt;Of &lt;/span&gt;Customer))
        &lt;span style="color: blue"&gt;If &lt;/span&gt;(&lt;span style="color: blue"&gt;Not &lt;/span&gt;(value) &lt;span style="color: blue"&gt;Is Nothing&lt;/span&gt;) &lt;span style="color: blue"&gt;Then
            CType&lt;/span&gt;(&lt;span style="color: blue"&gt;Me&lt;/span&gt;, IEntityWithRelationships).RelationshipManager. _
            InitializeRelatedReference(&lt;span style="color: blue"&gt;Of &lt;/span&gt;Customer)(&lt;span style="color: #a31515"&gt;&amp;quot;OMSModel.FK_Orders_Customer&amp;quot;&lt;/span&gt;, &lt;span style="color: #a31515"&gt;&amp;quot;Customer&amp;quot;&lt;/span&gt;, value)
        &lt;span style="color: blue"&gt;End If
    End Set
End Property&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;The Customer property is a navigation property to the parent Customer entity itself as we expect. The CustomerReference is an &lt;a href="http://msdn.microsoft.com/en-us/library/bb297956.aspx" target="_blank"&gt;EntityReference&lt;/a&gt; class. This class describes the &lt;strong&gt;relationship&lt;/strong&gt; between the Order and Customer. It also defines an event called &lt;a href="http://msdn.microsoft.com/en-us/library/system.data.objects.dataclasses.relatedend.associationchanged.aspx" target="_blank"&gt;AssociationChanged&lt;/a&gt; that you can handle to notify the UI properly when the reference changes. When you change the reference this event will fire twice, first to remove the old reference and then again to add the new one. You can easily extend the Order partial class by creating another &lt;a href="http://msdn.microsoft.com/en-us/library/yfzd5350.aspx" target="_blank"&gt;Partial Class declaration&lt;/a&gt; for Order in the same namespace (which is automatically imported in VB) and then calling the appropriate property change notifications:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;Imports &lt;/span&gt;System.ComponentModel

&lt;span style="color: blue"&gt;Partial Public Class &lt;/span&gt;Order
    &lt;span style="color: blue"&gt;Sub New&lt;/span&gt;()
        &lt;span style="color: blue"&gt;MyBase&lt;/span&gt;.New()
        &lt;span style="color: blue"&gt;AddHandler Me&lt;/span&gt;.CustomerReference.AssociationChanged, &lt;span style="color: blue"&gt;AddressOf &lt;/span&gt;Customer_AssociationChanged
    &lt;span style="color: blue"&gt;End Sub

    Private Sub &lt;/span&gt;Customer_AssociationChanged(&lt;span style="color: blue"&gt;ByVal &lt;/span&gt;sender &lt;span style="color: blue"&gt;As Object&lt;/span&gt;, _
                                            &lt;span style="color: blue"&gt;ByVal &lt;/span&gt;e &lt;span style="color: blue"&gt;As &lt;/span&gt;CollectionChangeEventArgs)
        &lt;span style="color: blue"&gt;If &lt;/span&gt;e.Action = CollectionChangeAction.Remove &lt;span style="color: blue"&gt;Then
            &lt;/span&gt;OnPropertyChanging(&lt;span style="color: #a31515"&gt;&amp;quot;Customer&amp;quot;&lt;/span&gt;)
        &lt;span style="color: blue"&gt;Else
            &lt;/span&gt;OnPropertyChanged(&lt;span style="color: #a31515"&gt;&amp;quot;Customer&amp;quot;&lt;/span&gt;)
        &lt;span style="color: blue"&gt;End If
    End Sub
End Class&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;So now we can change the Customer in the dropdown and the UI will be notified properly. Sweet. For more information on Entity Framework and data binding &lt;a href="http://msdn.microsoft.com/en-us/library/bb738469.aspx" target="_blank"&gt;see this topic in the MSDN library&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9587373" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Visual+Basic/default.aspx">Visual Basic</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/WPF/default.aspx">WPF</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/VS2008/default.aspx">VS2008</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/DevCenter/default.aspx">DevCenter</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Article/default.aspx">Article</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Data/default.aspx">Data</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Entity+Framework/default.aspx">Entity Framework</category></item><item><title>Data Binding WPF Lookup Combobox Values to EF Entities</title><link>http://blogs.msdn.com/bethmassi/archive/2009/04/30/data-binding-wpf-lookup-combobox-values-to-ef-entities.aspx</link><pubDate>Thu, 30 Apr 2009 17:57:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9576176</guid><dc:creator>Beth Massi</dc:creator><slash:comments>5</slash:comments><comments>http://blogs.msdn.com/bethmassi/comments/9576176.aspx</comments><wfw:commentRss>http://blogs.msdn.com/bethmassi/commentrss.aspx?PostID=9576176</wfw:commentRss><wfw:comment>http://blogs.msdn.com/bethmassi/rsscomments.aspx?PostID=9576176</wfw:comment><description>&lt;p&gt;It’s extremely common to have to hook up lookup tables on your data entry forms in order to populate foreign keys in a database. I’ve talked about how to do this in Winforms and WPF with Datasets and LINQ to SQL before:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/vbasic/cc788742.aspx" target="_blank"&gt;How Do I: Create a Lookup Combobox in WPF?&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/vbasic/dd239277.aspx" target="_blank"&gt;How Do I: Create a Master-Detail Data Entry Form in WPF?&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/vbasic/bb643829.aspx" target="_blank"&gt;How Do I: Create Lookup Lists?&lt;/a&gt;&amp;#160; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/bethmassi/archive/2008/02/07/creating-lookup-lists-with-linq-to-sql.aspx"&gt;Creating Lookup Lists with LINQ to SQL&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/bethmassi/archive/2008/02/06/related-data-binding-and-comboboxes-with-linq-to-sql.aspx"&gt;Related Data Binding and ComboBoxes with LINQ to SQL&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/bethmassi/archive/2007/04/25/tips-on-related-data-binding-and-comboboxes.aspx"&gt;Tips on Related Data Binding and ComboBoxes&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The common theme between all of these is that the data sources, either the LINQ to SQL classes or the DataTables that we bind to, uses a navigation path based on the foreign key and that foreign key is exposed as a property (or DataColumn). For instance if we have a Customer related to Orders we would have a CustomerID property on Orders. &lt;/p&gt;  &lt;p&gt;DataSets (like databases) rely on this type of navigation. So when you want to find the parent Customer of an Order you have to know the relation. Using typed datasets helps you more but you still end up having to know the details of relationships and foreign keys of the DataSet. That’s why people who are familiar with databases are usually comfortable with working with DataSets.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/DataBindingWPFLookupComboboxValuestoEFEn_F345/image_2.png"&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="236" alt="image" src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/DataBindingWPFLookupComboboxValuestoEFEn_F345/image_thumb.png" width="587" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;LINQ to SQL classes also include navigation properties as direct object references and collections. So they have both the foreign key and the navigation properties. Customer will have a collection of Orders and Order will have a reference back to Customer but the classes also contain the CustomerID property. This isn’t “pure” I suppose but it does make data binding and subsequent saves back to the database pretty much a no brainer. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/DataBindingWPFLookupComboboxValuestoEFEn_F345/image_4.png"&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="242" alt="image" src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/DataBindingWPFLookupComboboxValuestoEFEn_F345/image_thumb_1.png" width="553" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;For instance say I want to hook up a lookup combobox using a LINQ to SQL class on an Order with a reference to Customer. I want to display a list of Customers the user can pick from and that Customer should be associated with that Order. It’s pretty straight forward and works the same with DataTables.&lt;/p&gt;  &lt;p&gt;XAML:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Window.Resources&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;CollectionViewSource &lt;/span&gt;&lt;span style="color: red"&gt;x&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;Key&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;OrdersSource&amp;quot; /&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;CollectionViewSource &lt;/span&gt;&lt;span style="color: red"&gt;x&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;Key&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;CustomerLookup&amp;quot; /&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Window.Resources&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Grid &lt;/span&gt;&lt;span style="color: red"&gt;Grid.Row&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;1&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Name&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Grid1&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;DataContext&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color: #a31515"&gt;Binding &lt;/span&gt;&lt;span style="color: red"&gt;Source&lt;/span&gt;&lt;span style="color: blue"&gt;={&lt;/span&gt;&lt;span style="color: #a31515"&gt;StaticResource &lt;/span&gt;&lt;span style="color: red"&gt;OrdersSource&lt;/span&gt;&lt;span style="color: blue"&gt;}}&amp;quot;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;&amp;lt;ComboBox &lt;/span&gt;&lt;span style="color: red"&gt;Height&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;23&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Name&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;ComboBox1&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Width&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;177&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Margin&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;2&amp;quot;  &lt;/span&gt;&lt;span style="color: red"&gt;HorizontalAlignment&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Left&amp;quot; 
          &lt;/span&gt;&lt;span style="color: red"&gt;IsEditable&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;False&amp;quot;
          &lt;/span&gt;&lt;span style="color: red"&gt;ItemsSource&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color: #a31515"&gt;Binding &lt;/span&gt;&lt;span style="color: red"&gt;Source&lt;/span&gt;&lt;span style="color: blue"&gt;={&lt;/span&gt;&lt;span style="color: #a31515"&gt;StaticResource &lt;/span&gt;&lt;span style="color: red"&gt;CustomerLookup&lt;/span&gt;&lt;span style="color: blue"&gt;}}&amp;quot;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: red"&gt;          DisplayMemberPath&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;LastName&amp;quot;&lt;br /&gt;&lt;span style="color: red"&gt;          SelectedValuePath&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;CustomerID&amp;quot; &lt;/span&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;
&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;          &lt;/span&gt;&lt;span style="color: red"&gt;SelectedValue&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color: #a31515"&gt;Binding &lt;/span&gt;&lt;span style="color: red"&gt;Path&lt;/span&gt;&lt;span style="color: blue"&gt;=CustomerID}&amp;quot; 
          &lt;/span&gt;&lt;span style="color: blue"&gt;/&amp;gt;&lt;br /&gt;...&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Code-behind:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;Class &lt;/span&gt;Window1
    &lt;span style="color: blue"&gt;Private &lt;/span&gt;db &lt;span style="color: blue"&gt;As New &lt;/span&gt;MyDataObjectContext
    &lt;span style="color: blue"&gt;Private &lt;/span&gt;OrderData &lt;span style="color: blue"&gt;As &lt;/span&gt;IEnumerable(&lt;span style="color: blue"&gt;Of &lt;/span&gt;Order)

    &lt;span style="color: blue"&gt;Private Sub &lt;/span&gt;Window1_Loaded(&lt;span style="color: blue"&gt;ByVal &lt;/span&gt;sender &lt;span style="color: blue"&gt;As Object&lt;/span&gt;, &lt;span style="color: blue"&gt;ByVal &lt;/span&gt;e &lt;span style="color: blue"&gt;As &lt;/span&gt;System.Windows.RoutedEventArgs) &lt;span style="color: blue"&gt;Handles Me&lt;/span&gt;.Loaded
        &lt;span style="color: green"&gt;'Load all the orders from the database
        &lt;/span&gt;&lt;span style="color: blue"&gt;Me&lt;/span&gt;.OrderData = db.Orders
        &lt;span style="color: green"&gt;'Get the customer lookup list (this is the Combobox ItemsSource)
        &lt;/span&gt;&lt;span style="color: blue"&gt;Dim &lt;/span&gt;customerList = &lt;span style="color: blue"&gt;From &lt;/span&gt;c &lt;span style="color: blue"&gt;In &lt;/span&gt;db.Customers _
                           &lt;span style="color: blue"&gt;Where &lt;/span&gt;c.Orders.Count &amp;gt; 0 _
                           &lt;span style="color: blue"&gt;Order By &lt;/span&gt;c.LastName, c.FirstName

        &lt;span style="color: blue"&gt;Dim &lt;/span&gt;ordersSource = &lt;span style="color: blue"&gt;CType&lt;/span&gt;(&lt;span style="color: blue"&gt;Me&lt;/span&gt;.FindResource(&lt;span style="color: #a31515"&gt;&amp;quot;OrdersSource&amp;quot;&lt;/span&gt;), CollectionViewSource)
        ordersSource.Source = &lt;span style="color: blue"&gt;Me&lt;/span&gt;.OrderData
        &lt;span style="color: blue"&gt;Dim &lt;/span&gt;custSource = &lt;span style="color: blue"&gt;CType&lt;/span&gt;(&lt;span style="color: blue"&gt;Me&lt;/span&gt;.FindResource(&lt;span style="color: #a31515"&gt;&amp;quot;CustomerLookup&amp;quot;&lt;/span&gt;), CollectionViewSource)
        custSource.Source = customerList.ToList()

    &lt;span style="color: blue"&gt;End Sub&lt;br /&gt;...&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Almost all of this code is just to set up the context of this discussion, you can &lt;a href="http://msdn.microsoft.com/en-us/vbasic/dd239277.aspx" target="_blank"&gt;watch this video for details&lt;/a&gt; on building a complete example. Here I’m using CollectionViewSources in the XAML and setting their Source property in code. This technique is handy especially if you are using nested DataTemplates. The important piece to note are the four properties on the Combobox. ItemsSource, DisplayMemberPath, SelectedValue, and SelectedValuePath. To set up your combobox:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Set the ItemsSource to the list of Customers you want to display in the Combobox.&amp;#160; &lt;/li&gt;

  &lt;li&gt;Next set the DisplayMemberPath to the property name on this list that you want to use to display in the list, here I used LastName. &lt;/li&gt;

  &lt;li&gt;Then set the &lt;strong&gt;SelectedValuePath &lt;/strong&gt;to the property name on this list that will be used to populate the foreign key value on the Order. &lt;/li&gt;

  &lt;li&gt;Finally you set the &lt;strong&gt;SelectedValue&lt;/strong&gt; to the property binding on the Order that is foreign key. LINQ to SQL (and DataSets) will happily save your data with this binding in place. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is how you always bind DataTables and it also works well for LINQ to SQL classes. But since LINQ to SQL classes also include the navigation properties (the Orders collection on Customer and the Customer object reference on Order) you can use a different technique by binding directly to the Customer reference. This is the only choice we have with Entity Framework entities in .NET 3.5 SP1. &lt;/p&gt;

&lt;p&gt;What’s unique with Entity Framework is that the associations between other entities use &lt;strong&gt;only &lt;/strong&gt;navigation properties -- so there isn’t a CustomerID foreign key property value on the Order at all. &lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/DataBindingWPFLookupComboboxValuestoEFEn_F345/image_6.png"&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="279" alt="image" src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/DataBindingWPFLookupComboboxValuestoEFEn_F345/image_thumb_2.png" width="448" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;What you have to do instead is &lt;strong&gt;bind directly to the Customer &lt;/strong&gt;object reference. The change in the above example is the Combobox binding in XAML:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;ComboBox &lt;/span&gt;&lt;span style="color: red"&gt;Height&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;23&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Name&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;ComboBox1&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Width&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;177&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;Margin&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;2&amp;quot;  &lt;/span&gt;&lt;span style="color: red"&gt;HorizontalAlignment&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Left&amp;quot; 
          &lt;/span&gt;&lt;span style="color: red"&gt;IsEditable&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;False&amp;quot;
          &lt;/span&gt;&lt;span style="color: red"&gt;ItemsSource&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color: #a31515"&gt;Binding &lt;/span&gt;&lt;span style="color: red"&gt;Source&lt;/span&gt;&lt;span style="color: blue"&gt;={&lt;/span&gt;&lt;span style="color: #a31515"&gt;StaticResource &lt;/span&gt;&lt;span style="color: red"&gt;CustomerLookup&lt;/span&gt;&lt;span style="color: blue"&gt;}}&amp;quot;
&lt;span style="color: red"&gt;          DisplayMemberPath&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;LastName&amp;quot;&lt;/span&gt;          &lt;br /&gt;&lt;/span&gt;&lt;span style="color: red"&gt;          SelectedItem&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color: #a31515"&gt;Binding &lt;/span&gt;&lt;span style="color: red"&gt;Path&lt;/span&gt;&lt;span style="color: blue"&gt;=Customer}&amp;quot; 
          &lt;/span&gt;&lt;span style="color: blue"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;The important pieces in this case are the three properties on the Combobox. ItemsSource, DisplayMemberPath, and &lt;strong&gt;SelectedItem&lt;/strong&gt;. &lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Set the ItemsSource to the list of Customers you want to display in the Combobox -- same as before. &lt;/li&gt;

  &lt;li&gt;Next set the DisplayMemberPath to the property name on this list that you want to use to display in the list, here I used LastName – same as before. &lt;/li&gt;

  &lt;li&gt;Now set the &lt;strong&gt;SelectedItem&lt;/strong&gt; to the property binding on the Order that is the &lt;strong&gt;navigation property to Customer&lt;/strong&gt;. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This will work properly with LINQ to SQL classes and Entity Framework entities but there is one caveat. You need to make sure that you pull the &lt;strong&gt;entire Customer entity &lt;/strong&gt;into in the lookup list &lt;strong&gt;from the same ObjectContext &lt;/strong&gt;you used to query the Orders. This is because the same ObjectContext (DataContext in LINQ to SQL) needs to resolve the entity references between the queries. Entity Framework does this based on the EntityKeys. The neat side effect of this with EF is that you don’t have to pull down the Customers with the Orders query, they will automatically become references when the Customer lookup list is queried through the same context. (See &lt;a href="http://blogs.msdn.com/bethmassi/archive/2008/12/10/master-details-with-entity-framework-explicit-load.aspx" target="_blank"&gt;my post on explicit load for more details&lt;/a&gt; on how to bring down related EF entities when you only make one call.)&lt;/p&gt;

&lt;p&gt;This behavior may be desired in a lot of scenarios but if we do not need to modify the Customer, like in our example, this can be overkill especially if the Customer has a lot of large fields you aren’t using. In the first example we could have only pulled a subset of fields from the Customer table – the only required ones would be the ones used in the data binding, CustomerID and LastName. So with DataTables and LINQ to SQL classes that bind on the values we could have optimized our lookup list query to:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;Dim &lt;/span&gt;customerList = &lt;span style="color: blue"&gt;From &lt;/span&gt;c &lt;span style="color: blue"&gt;In &lt;/span&gt;db.Customers _
                   &lt;span style="color: blue"&gt;Where &lt;/span&gt;c.Orders.Count &amp;gt; 0 _
                   &lt;span style="color: blue"&gt;Order By &lt;/span&gt;c.LastName, c.FirstName _
                   &lt;span style="color: blue"&gt;Select &lt;/span&gt;c.CustomerID, c.LastName&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;This &lt;strong&gt;will not work &lt;/strong&gt;if we bind directly to the navigation properties because the customerList is now a list of anonymous types and not a list of Customer entities. So binding to the values gives you greater flexibility with your lookup list queries. Unfortunately in the current version of EF you cannot bind this way but they are planning to enable this in the next version. In .NET 4.0 the EF team will add support for a new type of association called &amp;quot;FK Associations&amp;quot;. &lt;a href="http://blogs.msdn.com/efdesign/archive/2009/03/16/foreign-keys-in-the-entity-framework.aspx" target="_blank"&gt;Read more about that here.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And I’m working on the next set of &lt;a href="http://msdn.microsoft.com/en-us/vbasic/bb466226.aspx#wpfdata" target="_blank"&gt;WPF Forms over Data How Do I videos&lt;/a&gt;, this time with Entity Framework, that will hopefully explain how to use EF in practical way by building WPF data applications. Stay tuned!&lt;/p&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9576176" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Visual+Basic/default.aspx">Visual Basic</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/WPF/default.aspx">WPF</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/LINQ/default.aspx">LINQ</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/VS2008/default.aspx">VS2008</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/DevCenter/default.aspx">DevCenter</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Article/default.aspx">Article</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Data/default.aspx">Data</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Entity+Framework/default.aspx">Entity Framework</category></item><item><title>Programming Entity Framework Book</title><link>http://blogs.msdn.com/bethmassi/archive/2009/02/17/programming-entity-framework-book.aspx</link><pubDate>Wed, 18 Feb 2009 05:11:16 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9429457</guid><dc:creator>Beth Massi</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/bethmassi/comments/9429457.aspx</comments><wfw:commentRss>http://blogs.msdn.com/bethmassi/commentrss.aspx?PostID=9429457</wfw:commentRss><wfw:comment>http://blogs.msdn.com/bethmassi/rsscomments.aspx?PostID=9429457</wfw:comment><description>&lt;p&gt;&lt;a href="http://learnentityframework.com/" target="_blank"&gt;Julie Lerman's&lt;/a&gt; &lt;a href="http://www.amazon.com/Programming-Entity-Framework-Julia-Lerman/dp/059652028X" target="_blank"&gt;&lt;em&gt;Programming Entity Framework&lt;/em&gt; book&lt;/a&gt; just arrived today! I've been skimming around it all day and so far Chapter 8 is my favorite but I'm sure once I get to Chapter 14 that will take the cake :-)&lt;/p&gt;  &lt;p&gt;Thanks Julie! (especially for all the great VB code!) &lt;/p&gt;  &lt;p&gt;How Do I videos here we come.....&lt;/p&gt;  &lt;p&gt;Enjoy!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9429457" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Visual+Basic/default.aspx">Visual Basic</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Community/default.aspx">Community</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/DevCenter/default.aspx">DevCenter</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Entity+Framework/default.aspx">Entity Framework</category></item><item><title>OBA Part 1 - Exposing Line-of-Business Data</title><link>http://blogs.msdn.com/bethmassi/archive/2009/02/03/oba-part-1-exposing-line-of-business-data.aspx</link><pubDate>Wed, 04 Feb 2009 01:23:24 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9393912</guid><dc:creator>Beth Massi</dc:creator><slash:comments>11</slash:comments><comments>http://blogs.msdn.com/bethmassi/comments/9393912.aspx</comments><wfw:commentRss>http://blogs.msdn.com/bethmassi/commentrss.aspx?PostID=9393912</wfw:commentRss><wfw:comment>http://blogs.msdn.com/bethmassi/rsscomments.aspx?PostID=9393912</wfw:comment><description>&lt;p&gt;Last post I talked about the &lt;a href="http://blogs.msdn.com/bethmassi/archive/2009/02/02/building-an-office-business-application-for-techready-8.aspx" target="_blank"&gt;high-level architecture of our &lt;strong&gt;O&lt;/strong&gt;ffice &lt;strong&gt;B&lt;/strong&gt;usiness &lt;strong&gt;A&lt;/strong&gt;pplication&lt;/a&gt; for the new Northwind Traders. There are a lot of different architecture options to consider when building an OBA. OBA is all about using Microsoft Office with your Line of Business (LOB) data. Whether that involves using SharePoint as well depends on the application. Since we wanted to store the unstructured data (the Northwind customer P.O.)&lt;a href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/OBAPart1ExposingLineofBusinessData_8D7A/OBAdiagram_2.jpg"&gt;&lt;img style="margin: 5px 10px 0px 0px" height="159" alt="OBAdiagram" src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/OBAPart1ExposingLineofBusinessData_8D7A/OBAdiagram_thumb.jpg" width="156" align="left" border="0" /&gt;&lt;/a&gt; SharePoint is a good fit here.&lt;/p&gt;  &lt;p&gt;There are a lot of options when thinking about how to expose your LOB data. For instance, you may already have a service oriented architecture at the enterprise that exposes data contracts and processes that you can consume from Office clients. Or maybe you have a small business and have decided to expose &lt;font color="#ff0000"&gt;&lt;font color="#000000"&gt;&lt;a href="http://msdn.microsoft.com/en-us/vbasic/cc138242.aspx" target="_blank"&gt;a simple service that returns and consumes n-tier DataSets&lt;/a&gt;&lt;/font&gt; &lt;/font&gt;directly. Or you already have a custom LOB data entry system using custom business objects and you want to reuse the business layer in the Office client. OBA doesn't dictate &lt;em&gt;how &lt;/em&gt;you expose this data. Because you can consume data in Office clients the same way you do in Windows apps the same types of decisions need to be made. &lt;/p&gt;  &lt;p&gt;When we sat down to write the new Northwind Traders application we thought about how our data would need to behave and what would be the best way for all the pieces to easily update and query the Northwind database. Because there was only going to be simple validations needed on the data and mostly CRUD operations we opted to expose an Entity Data Model via ADO.NET Data Services &lt;a href="http://blogs.msdn.com/bethmassi/archive/2009/01/09/using-ado-net-data-services.aspx" target="_blank"&gt;like I showed before&lt;/a&gt;. This allowed us to get a secure service up and running in minutes. &lt;/p&gt;  &lt;p&gt;We did make some minor changes to our old friend, the &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=06616212-0356-46A0-8DA2-EEBC53A68034&amp;amp;displaylang=en" target="_blank"&gt;Northwind database&lt;/a&gt;. First, since we wanted to be able to look up order history for a customer when they emailed the sales reps, we needed to add an EmailAddress field to the Customers table (amazing that we didn't have that field before!). We also added it to the Employees table. &lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;ALTER TABLE &lt;/span&gt;dbo.Customers &lt;span style="color: blue"&gt;ADD
    &lt;/span&gt;EmailAddress &lt;span style="color: blue"&gt;varchar&lt;/span&gt;(50) &lt;span style="color: blue"&gt;NULL
&lt;/span&gt;GO
&lt;span style="color: blue"&gt;ALTER TABLE &lt;/span&gt;dbo.Employees &lt;span style="color: blue"&gt;ADD
    &lt;/span&gt;EmailAddress &lt;span style="color: blue"&gt;varchar&lt;/span&gt;(50) &lt;span style="color: blue"&gt;NULL
&lt;/span&gt;GO&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Then we populated the data with some customers and employees that were actually folks on our team because we need real email addresses to work with :-)&lt;/p&gt;

&lt;p&gt;Next I created a new ASP.NET Web Application and added an ADO.NET Data Service and an Entity Data Model just like how &lt;a href="http://blogs.msdn.com/bethmassi/archive/2009/01/09/using-ado-net-data-services.aspx" target="_blank"&gt;I showed in this post&lt;/a&gt;. (You will need &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=27673c47-b3b5-4c67-bd99-84e525b5ce61&amp;amp;displaylang=en" target="_blank"&gt;Visual Studio 2008 Service Pack 1&lt;/a&gt; in order to get these new item templates.) For testing we set the service to allow full access to all the entities in the model&amp;#160; -- we'll lock it down later. I also am passing detailed errors which we won't want to do once we're in production:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;Public Class &lt;/span&gt;Northwind
    &lt;span style="color: blue"&gt;Inherits &lt;/span&gt;DataService(&lt;span style="color: blue"&gt;Of &lt;/span&gt;NorthwindEntities)

    &lt;span style="color: green"&gt;' This method is called only once to initialize service-wide policies.
    &lt;/span&gt;&lt;span style="color: blue"&gt;Public Shared Sub &lt;/span&gt;InitializeService(&lt;span style="color: blue"&gt;ByVal &lt;/span&gt;config &lt;span style="color: blue"&gt;As &lt;/span&gt;IDataServiceConfiguration)
        config.SetEntitySetAccessRule(&lt;span style="color: #a31515"&gt;&amp;quot;*&amp;quot;&lt;/span&gt;, EntitySetRights.All)
        config.UseVerboseErrors = &lt;span style="color: blue"&gt;True
    End Sub&lt;br /&gt;End Class&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;One thing we did want to do is set up our data model so that it enforced constraints (i.e. there cannot be an Order without a Customer) but since some of our legacy data didn't specify all of these constraints we made the changes to the model instead, so that the integrity on all new data would be enforced through the service. This is often the case in projects, you cannot change the legacy databases but you still need to work with proper data models. So we changed the EDM so that all the entities were singular and not plural (Customer instead of Customers, Order instead of Orders, etc). We also changed the associations so that they were enforced and so that one to many collections were plural and the one-to-one were singular (i.e. Order has Order_Details collection and Order_Detail has Product reference). You can modify these from the Properties window of the &lt;font color="#ff0000"&gt;&lt;font color="#000000"&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/bb738482.aspx" target="_blank"&gt;Entity Data Model Designer.&lt;/a&gt;&lt;/font&gt; &lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/OBAPart1ExposingLineofBusinessData_8D7A/OBAedm_4.jpg"&gt;&lt;img height="475" alt="OBAedm" src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/OBAPart1ExposingLineofBusinessData_8D7A/OBAedm_thumb_1.jpg" width="641" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Once I have the model and the data service code set up we can hit F5 and navigate our browser to the Northwind.svc and test the call to pull up all the customers (i.e. http://localhost:1234/Northwind.svc/Customers) just like how &lt;a href="http://blogs.msdn.com/bethmassi/archive/2009/01/09/using-ado-net-data-services.aspx" target="_blank"&gt;I showed in this post&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now that we have our data exposed as a data service we can build the Office clients to interact with it just like I showed before &lt;a href="http://blogs.msdn.com/bethmassi/archive/2009/01/22/ado-net-data-services-building-an-excel-client.aspx" target="_blank"&gt;here when we built a simple Excel client&lt;/a&gt;. Next post I'll show how we can use WPF controls in an Outlook Add-In in order to display the customer order history by querying the data through the data service. &lt;/p&gt;

&lt;p&gt;Until next time...&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9393912" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/bethmassi/archive/tags/VS2008/default.aspx">VS2008</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/DevCenter/default.aspx">DevCenter</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Article/default.aspx">Article</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Data/default.aspx">Data</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Entity+Framework/default.aspx">Entity Framework</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/ADO.NET+Data+Services/default.aspx">ADO.NET Data Services</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/OBA/default.aspx">OBA</category></item><item><title>ADO.NET Data Services - Intercepting Queries and Adding Validation</title><link>http://blogs.msdn.com/bethmassi/archive/2009/01/21/ado-net-data-services-intercepting-queries-and-adding-validation.aspx</link><pubDate>Thu, 22 Jan 2009 07:53:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9362890</guid><dc:creator>Beth Massi</dc:creator><slash:comments>6</slash:comments><comments>http://blogs.msdn.com/bethmassi/comments/9362890.aspx</comments><wfw:commentRss>http://blogs.msdn.com/bethmassi/commentrss.aspx?PostID=9362890</wfw:commentRss><wfw:comment>http://blogs.msdn.com/bethmassi/rsscomments.aspx?PostID=9362890</wfw:comment><description>&lt;P&gt;Last few posts I've been building a WPF client against ADO.NET Data Services, if you missed them:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/bethmassi/archive/2009/01/09/using-ado-net-data-services.aspx" target=_blank mce_href="http://blogs.msdn.com/bethmassi/archive/2009/01/09/using-ado-net-data-services.aspx"&gt;Using ADO.NET Data Services&lt;/A&gt; &lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/bethmassi/archive/2009/01/15/ado-net-data-services-building-a-wpf-client.aspx" target=_blank mce_href="http://blogs.msdn.com/bethmassi/archive/2009/01/15/ado-net-data-services-building-a-wpf-client.aspx"&gt;ADO.NET Data Services - Building a WPF Client&lt;/A&gt; &lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/bethmassi/archive/2009/01/20/ado-net-data-services-enforcing-fk-associations-and-a-fix-for-deleting-entities.aspx" target=_blank mce_href="http://blogs.msdn.com/bethmassi/archive/2009/01/20/ado-net-data-services-enforcing-fk-associations-and-a-fix-for-deleting-entities.aspx"&gt;ADO.NET Data Services - Enforcing FK Associations and a Fix for Deleting Entities&lt;/A&gt; &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Today I want to show you how we can add validation or any other extra processing when data is queried from the data service as well as when we attempt to make changes to the data. &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Ways of Querying a ADO.NET Data Service&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;First let's recap how we can query a data service. In our WPF client we've been taking advantage of LINQ but that's not the only way to send queries to the service. Because we're using the data service client framework we can write LINQ queries against the service and the client handles translating the queries into HTTP GETs. But we could also easily specify the raw URI's to send to the service. For instance, when we want to fill a combobox of categories ordered by CategoryName we could do this instead:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;Imports &lt;/SPAN&gt;System.Data.Services.Client&lt;BR&gt;.&lt;BR&gt;.&lt;BR&gt;&lt;SPAN style="COLOR: green"&gt;'Use the untyped DataServiceContext and pass URIs.
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Dim &lt;/SPAN&gt;ctx &lt;SPAN style="COLOR: blue"&gt;As New &lt;/SPAN&gt;DataServiceContext(&lt;SPAN style="COLOR: blue"&gt;New &lt;/SPAN&gt;Uri(&lt;SPAN style="COLOR: #a31515"&gt;"http://localhost:1234/Northwind.svc"&lt;/SPAN&gt;))
&lt;SPAN style="COLOR: green"&gt;'Explicitly execute the the HTTP GET
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Dim &lt;/SPAN&gt;cats = ctx.Execute(&lt;SPAN style="COLOR: blue"&gt;Of &lt;/SPAN&gt;Category)(&lt;SPAN style="COLOR: blue"&gt;New &lt;/SPAN&gt;Uri(&lt;SPAN style="COLOR: #a31515"&gt;"Categories?$orderby=CategoryName"&lt;/SPAN&gt;, UriKind.Relative))
&lt;SPAN style="COLOR: green"&gt;'Display results in a combobox
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.cboCategoryLookup.ItemsSource = cats.ToList()&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;In the code above the query is explicitly executed on the second line. You can achieve the same response by typing &lt;STRONG&gt;http://localhost:1234/Northwind.svc/Categories?$orderby=CategoryName &lt;/STRONG&gt;in the address bar of your browser.&lt;/P&gt;
&lt;P&gt;However one of the benefits of adding a service reference to our client is that it generates a proxy that inherits from the DataServiceContext that allows typed access to the entity sets that we're exposing from our service. This makes our code cleaner so we can write a LINQ query to do the same job instead:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;Imports &lt;/SPAN&gt;WpfClient.NorthwindService&lt;BR&gt;.&lt;BR&gt;.&lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;Dim &lt;/SPAN&gt;ctx &lt;SPAN style="COLOR: blue"&gt;As New &lt;/SPAN&gt;NorthwindEntities(&lt;SPAN style="COLOR: blue"&gt;New &lt;/SPAN&gt;Uri(&lt;SPAN style="COLOR: #a31515"&gt;"http://localhost:1234/Northwind.svc"&lt;/SPAN&gt;))

&lt;SPAN style="COLOR: green"&gt;'Use LINQ to query the service instead
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Dim &lt;/SPAN&gt;cats = &lt;SPAN style="COLOR: blue"&gt;From &lt;/SPAN&gt;c &lt;SPAN style="COLOR: blue"&gt;In &lt;/SPAN&gt;ctx.Categories _
           &lt;SPAN style="COLOR: blue"&gt;Order By &lt;/SPAN&gt;c.CategoryName

&lt;SPAN style="COLOR: green"&gt;'Display results in a combobox. 
'The query is executed when we access the results (calling ToList())
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.cboCategoryLookup.ItemsSource = cats.ToList()&lt;/PRE&gt;
&lt;P&gt;Notice however that there is a subtle difference in this code that you should be aware of. When you write a LINQ query it never executes unless you access the results. In this case we're accessing the results when we call ToList() on the query. This is called deferred execution and it's something to be aware of. But if we look in Fiddler then we can see that the exact same HTTP GET is sent to the service: &lt;STRONG&gt;http://localhost:1234/Northwind.svc/Categories?$orderby=CategoryName &lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;This also means that not every LINQ query can be translated into an HTTP GET. For instance, what if we just wanted to display a couple properties of the category in the combobox. You would think we'd be able to do something like this:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;Dim &lt;/SPAN&gt;cats = &lt;SPAN style="COLOR: blue"&gt;From &lt;/SPAN&gt;c &lt;SPAN style="COLOR: blue"&gt;In &lt;/SPAN&gt;ctx.Categories _
           &lt;SPAN style="COLOR: blue"&gt;Order By &lt;/SPAN&gt;c.CategoryName _
           &lt;SPAN style="COLOR: blue"&gt;Select &lt;/SPAN&gt;c.CategoryName, c.Description&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;Unfortunately if you try to do this you'll get a NotSupportedException thrown at you by the client framework because it can't translate the query into an HTTP GET. In this case you need to pull down the category entities you want first and then you can project over those to create a list of anonymous types with only the properties you specify. But remember that you need to "execute" the query against the service first and then query over the list that is returned. Here's a way to do this:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;Dim &lt;/SPAN&gt;cats = &lt;SPAN style="COLOR: blue"&gt;From &lt;/SPAN&gt;c &lt;SPAN style="COLOR: blue"&gt;In &lt;/SPAN&gt;ctx.Categories _
           &lt;SPAN style="COLOR: blue"&gt;Order By &lt;/SPAN&gt;c.CategoryName

&lt;SPAN style="COLOR: green"&gt;'Now project only the properties we want. 
' Call ToList() on the first query to execute the service call
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Dim &lt;/SPAN&gt;results = &lt;SPAN style="COLOR: blue"&gt;From &lt;/SPAN&gt;c &lt;SPAN style="COLOR: blue"&gt;In &lt;/SPAN&gt;cats.ToList() _
              &lt;SPAN style="COLOR: blue"&gt;Select &lt;/SPAN&gt;c.CategoryName, c.Description&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;For more details on what is and isn't supported &lt;A href="http://msdn.microsoft.com/en-us/library/cc907912.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/cc907912.aspx"&gt;refer to this article&lt;/A&gt;. &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Intercepting Queries&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Now that we understand how queries work we can start messing with how they execute. :-) Say we want to query only the Products in Northwind that are not Discontinued. We could write the query against our data service that specified the filter like so:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;Dim &lt;/SPAN&gt;products = &lt;SPAN style="COLOR: blue"&gt;From &lt;/SPAN&gt;p &lt;SPAN style="COLOR: blue"&gt;In &lt;/SPAN&gt;ctx.Products _
               &lt;SPAN style="COLOR: blue"&gt;Where &lt;/SPAN&gt;p.Discontinued = &lt;SPAN style="COLOR: blue"&gt;False &lt;/SPAN&gt;_
               &lt;SPAN style="COLOR: blue"&gt;Order By &lt;/SPAN&gt;p.ProductName&lt;/PRE&gt;
&lt;P&gt;Or we could write the raw URI:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;Dim &lt;/SPAN&gt;productURI &lt;SPAN style="COLOR: blue"&gt;As New &lt;/SPAN&gt;Uri(&lt;SPAN style="COLOR: #a31515"&gt;"Products()?$filter=Discontinued%20eq%20false&amp;amp;$orderby=ProductName"&lt;/SPAN&gt;, _
                          UriKind.Relative)

&lt;SPAN style="COLOR: blue"&gt;Dim &lt;/SPAN&gt;products = ctx.Execute(&lt;SPAN style="COLOR: blue"&gt;Of &lt;/SPAN&gt;Product)(productURI)&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;But what if it was a new requirement of the entire system that nowhere should we be displaying discontinued products? If this is the case we should be enforcing this on our data service instead. This can be done using &lt;A href="http://msdn.microsoft.com/en-us/library/cc668788.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/cc668788.aspx"&gt;query interceptors&lt;/A&gt; on the service. The way we create these is we annotate a method on our service with the &lt;A href="http://msdn.microsoft.com/en-us/library/system.data.services.queryinterceptorattribute.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/system.data.services.queryinterceptorattribute.aspx"&gt;QueryInterceptor attribute&lt;/A&gt;. The method you write must follow these rules:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;The method must have public scope and be annotated with the QueryInterceptorAttribute, taking the name of a entity set as a parameter. &lt;/LI&gt;
&lt;LI&gt;The method must accept no parameters. &lt;/LI&gt;
&lt;LI&gt;The method must return an expression of type System.Linq.Expressions.Expression(Of Func(Of T, Boolean)) that is the filter to be composed for the entity set. &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;The first two requirements are easy the third may be confusing if you've never played with &lt;A href="http://msdn.microsoft.com/en-us/library/bb531253.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/bb531253.aspx"&gt;lambda expressions&lt;/A&gt;. Basically what happens is you specify additional filtering to apply onto the incoming query via this lambda. So in order to append our condition that we should only be returning products that are not discontinued we can add this method to our data service:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;Imports &lt;/SPAN&gt;System.Data.Services
&lt;SPAN style="COLOR: blue"&gt;Imports &lt;/SPAN&gt;System.Linq
&lt;SPAN style="COLOR: blue"&gt;Imports &lt;/SPAN&gt;System.ServiceModel.Web
&lt;SPAN style="COLOR: blue"&gt;Imports &lt;/SPAN&gt;System.Linq.Expressions

&lt;SPAN style="COLOR: blue"&gt;Public Class &lt;/SPAN&gt;Northwind
    &lt;SPAN style="COLOR: blue"&gt;Inherits &lt;/SPAN&gt;DataService(&lt;SPAN style="COLOR: blue"&gt;Of &lt;/SPAN&gt;NorthwindEntities)   &lt;/PRE&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: green"&gt;    ' This method is called only once to initialize service-wide policies.
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Public Shared Sub &lt;/SPAN&gt;InitializeService(&lt;SPAN style="COLOR: blue"&gt;ByVal &lt;/SPAN&gt;config &lt;SPAN style="COLOR: blue"&gt;As &lt;/SPAN&gt;IDataServiceConfiguration)
        config.SetEntitySetAccessRule(&lt;SPAN style="COLOR: #a31515"&gt;"Products"&lt;/SPAN&gt;, EntitySetRights.All)
        config.SetEntitySetAccessRule(&lt;SPAN style="COLOR: #a31515"&gt;"Categories"&lt;/SPAN&gt;, EntitySetRights.All)
&lt;SPAN style="COLOR: blue"&gt;    End Sub&lt;/SPAN&gt;&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;&lt;PRE class=code&gt;&lt;STRONG&gt;    &amp;lt;QueryInterceptor(&lt;SPAN style="COLOR: #a31515"&gt;"Products"&lt;/SPAN&gt;)&amp;gt; _
    &lt;SPAN style="COLOR: blue"&gt;Public Function &lt;/SPAN&gt;FilterProducts() &lt;SPAN style="COLOR: blue"&gt;As &lt;/SPAN&gt;Expression(&lt;SPAN style="COLOR: blue"&gt;Of &lt;/SPAN&gt;Func(&lt;SPAN style="COLOR: blue"&gt;Of &lt;/SPAN&gt;Product, &lt;SPAN style="COLOR: blue"&gt;Boolean&lt;/SPAN&gt;))
        &lt;/STRONG&gt;&lt;STRONG&gt;&lt;SPAN style="COLOR: green"&gt;'Only return products that are not discontinued
        &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Return Function&lt;/SPAN&gt;(p) p.Discontinued = &lt;/STRONG&gt;&lt;SPAN style="COLOR: blue"&gt;&lt;STRONG&gt;False
    End Function&lt;/STRONG&gt;

End Class&lt;/SPAN&gt;&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;Now we can write our queries without specifying the additional filter on discontinued and this will not be sent to the service from our client in the HTTP GET but will be executed against our database. The query interceptor will execute regardless if we write a LINQ query or feed it the raw URI.&lt;/P&gt;
&lt;P&gt;LINQ Query:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;Dim &lt;/SPAN&gt;products = &lt;SPAN style="COLOR: blue"&gt;From &lt;/SPAN&gt;p &lt;SPAN style="COLOR: blue"&gt;In &lt;/SPAN&gt;ctx.Products &lt;SPAN style="COLOR: blue"&gt;Order By &lt;/SPAN&gt;p.ProductName
&lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.ListView1.ItemsSource = products.ToList()&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;URI:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;Dim &lt;/SPAN&gt;productURI &lt;SPAN style="COLOR: blue"&gt;As New &lt;/SPAN&gt;Uri(&lt;SPAN style="COLOR: #a31515"&gt;"Products()?$orderby=ProductName"&lt;/SPAN&gt;, UriKind.Relative)
&lt;SPAN style="COLOR: blue"&gt;Dim &lt;/SPAN&gt;products = ctx.Execute(&lt;SPAN style="COLOR: blue"&gt;Of &lt;/SPAN&gt;Product)(productURI)
&lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.ListView1.ItemsSource = products.ToList()&lt;/PRE&gt;&lt;PRE class=code&gt;&lt;A href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/ADO.NETDataServicesInterceptingQueriesan_C65B/AstoriaQuery1_2.jpg" mce_href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/ADO.NETDataServicesInterceptingQueriesan_C65B/AstoriaQuery1_2.jpg"&gt;&lt;IMG height=549 alt=AstoriaQuery1 src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/ADO.NETDataServicesInterceptingQueriesan_C65B/AstoriaQuery1_thumb.jpg" width=644 border=0 mce_src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/ADO.NETDataServicesInterceptingQueriesan_C65B/AstoriaQuery1_thumb.jpg"&gt;&lt;/A&gt; &lt;/PRE&gt;
&lt;P&gt;Pretty slick. You could of course do other processing here first. And you can also specify your own additional &lt;A href="http://msdn.microsoft.com/en-us/library/cc668788.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/cc668788.aspx"&gt;service operations&lt;/A&gt; as well by attributing them with a &amp;lt;WebGet&amp;gt; attribute. More on those in a later post.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Validation with Change Interceptors&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;You can also add methods to your service that will execute when changes are submitted. This allows us to add validation or other processing onto the data being submitted to the database. You do this by attributing a method in the data service with the &lt;A href="http://msdn.microsoft.com/en-us/library/system.data.services.changeinterceptorattribute.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/system.data.services.changeinterceptorattribute.aspx"&gt;ChangeInterceptor attribute&lt;/A&gt;. A change interceptor will pass the entity being saved and a parameter that indicates what update operation is being performed. For instance, say we want to put a validation on our ProductName so that users cannot submit empty product names to the database. We could write a method in our data service like so:&lt;/P&gt;&lt;PRE class=code&gt;&amp;lt;ChangeInterceptor(&lt;SPAN style="COLOR: #a31515"&gt;"Products"&lt;/SPAN&gt;)&amp;gt; _
&lt;SPAN style="COLOR: blue"&gt;Public Sub &lt;/SPAN&gt;OnChangeProducts(&lt;SPAN style="COLOR: blue"&gt;ByVal &lt;/SPAN&gt;p &lt;SPAN style="COLOR: blue"&gt;As &lt;/SPAN&gt;Product, &lt;SPAN style="COLOR: blue"&gt;ByVal &lt;/SPAN&gt;ops &lt;SPAN style="COLOR: blue"&gt;As &lt;/SPAN&gt;UpdateOperations)
    &lt;SPAN style="COLOR: blue"&gt;If &lt;/SPAN&gt;ops = UpdateOperations.Add &lt;SPAN style="COLOR: blue"&gt;OrElse &lt;/SPAN&gt;ops = UpdateOperations.Change &lt;SPAN style="COLOR: blue"&gt;Then
        &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;'Do not allow products with empty names
        &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;If &lt;/SPAN&gt;p.ProductName = &lt;SPAN style="COLOR: #a31515"&gt;"" &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Then
            Throw New &lt;/SPAN&gt;DataServiceException(400, &lt;SPAN style="COLOR: #a31515"&gt;"Product name cannot be empty"&lt;/SPAN&gt;)
        &lt;SPAN style="COLOR: blue"&gt;End If
    End If
End Sub&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P&gt;When we throw a DataServiceException we can specify the HTTP status code and the message to return to the client. 400 indicates "Bad Request" and we pass the message on what the problem was. So if we try to submit a new or existing product with no product name we will get an HTTP error as seen in Fiddler:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/ADO.NETDataServicesInterceptingQueriesan_C65B/AstoriaChange1_2.jpg" mce_href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/ADO.NETDataServicesInterceptingQueriesan_C65B/AstoriaChange1_2.jpg"&gt;&lt;IMG height=768 alt=AstoriaChange1 src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/ADO.NETDataServicesInterceptingQueriesan_C65B/AstoriaChange1_thumb.jpg" width=712 border=0 mce_src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/ADO.NETDataServicesInterceptingQueriesan_C65B/AstoriaChange1_thumb.jpg"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;This is what's happening on the wire when we call SaveChanges and the exception is caught on the client. This prevents our data from being invalid no matter what client it's coming from. However this isn't that user-friendly to say the least. If we're building a smart client it's much better to put this type of validations on the client as well. &lt;/P&gt;
&lt;P&gt;We can do this in our WPF client by extending the Product partial class and implementing IDataErrorInfo and adding our validation. On the WPF client create a new class called Product and place it in the same exact namespace as the NorthwindEntities data service client proxy that is generated for us when we add the service reference. It's called NorthwindService in our case. Then we can overwrite the partial method OnProductNameChanging to do the client-side validation. This method is called from the ProductName property setter in the generated entity on the client. Here's an example of how we can collect validation messages on the Product.&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;Imports &lt;/SPAN&gt;WpfClient.NorthwindService
&lt;SPAN style="COLOR: blue"&gt;Imports &lt;/SPAN&gt;System.ComponentModel

&lt;SPAN style="COLOR: blue"&gt;Namespace &lt;/SPAN&gt;NorthwindService

    &lt;SPAN style="COLOR: blue"&gt;Partial Public Class &lt;/SPAN&gt;Product
        &lt;SPAN style="COLOR: blue"&gt;Implements &lt;/SPAN&gt;IDataErrorInfo

        &lt;SPAN style="COLOR: blue"&gt;Private Sub &lt;/SPAN&gt;OnProductNameChanging(&lt;SPAN style="COLOR: blue"&gt;ByVal &lt;/SPAN&gt;value &lt;SPAN style="COLOR: blue"&gt;As String&lt;/SPAN&gt;)
            &lt;SPAN style="COLOR: blue"&gt;If &lt;/SPAN&gt;value &lt;SPAN style="COLOR: blue"&gt;Is Nothing OrElse &lt;/SPAN&gt;value.Trim = &lt;SPAN style="COLOR: #a31515"&gt;"" &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Then
                Me&lt;/SPAN&gt;.AddError(&lt;SPAN style="COLOR: #a31515"&gt;"ProductName"&lt;/SPAN&gt;, &lt;SPAN style="COLOR: #a31515"&gt;"Product name cannot be empty"&lt;/SPAN&gt;)
            &lt;SPAN style="COLOR: blue"&gt;Else
                Me&lt;/SPAN&gt;.RemoveError(&lt;SPAN style="COLOR: #a31515"&gt;"ProductName"&lt;/SPAN&gt;)
            &lt;SPAN style="COLOR: blue"&gt;End If
        End Sub

#Region &lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;"IDataErrorInfo Members"
        &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Private &lt;/SPAN&gt;m_validationErrors &lt;SPAN style="COLOR: blue"&gt;As New &lt;/SPAN&gt;Dictionary(&lt;SPAN style="COLOR: blue"&gt;Of String&lt;/SPAN&gt;, &lt;SPAN style="COLOR: blue"&gt;String&lt;/SPAN&gt;)

        &lt;SPAN style="COLOR: blue"&gt;Private Sub &lt;/SPAN&gt;AddError(&lt;SPAN style="COLOR: blue"&gt;ByVal &lt;/SPAN&gt;columnName &lt;SPAN style="COLOR: blue"&gt;As String&lt;/SPAN&gt;, &lt;SPAN style="COLOR: blue"&gt;ByVal &lt;/SPAN&gt;msg &lt;SPAN style="COLOR: blue"&gt;As String&lt;/SPAN&gt;)
            &lt;SPAN style="COLOR: blue"&gt;If Not &lt;/SPAN&gt;m_validationErrors.ContainsKey(columnName) &lt;SPAN style="COLOR: blue"&gt;Then
                &lt;/SPAN&gt;m_validationErrors.Add(columnName, msg)
            &lt;SPAN style="COLOR: blue"&gt;End If
        End Sub

        Private Sub &lt;/SPAN&gt;RemoveError(&lt;SPAN style="COLOR: blue"&gt;ByVal &lt;/SPAN&gt;columnName &lt;SPAN style="COLOR: blue"&gt;As String&lt;/SPAN&gt;)
            &lt;SPAN style="COLOR: blue"&gt;If &lt;/SPAN&gt;m_validationErrors.ContainsKey(columnName) &lt;SPAN style="COLOR: blue"&gt;Then
                &lt;/SPAN&gt;m_validationErrors.Remove(columnName)
            &lt;SPAN style="COLOR: blue"&gt;End If
        End Sub

        Friend ReadOnly Property &lt;/SPAN&gt;HasErrors() &lt;SPAN style="COLOR: blue"&gt;As Boolean
            Get
                Return &lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;Me&lt;/SPAN&gt;.Error &lt;SPAN style="COLOR: blue"&gt;IsNot Nothing&lt;/SPAN&gt;)
            &lt;SPAN style="COLOR: blue"&gt;End Get
        End Property

        Friend ReadOnly Property &lt;/SPAN&gt;[Error]() &lt;SPAN style="COLOR: blue"&gt;As String _&lt;BR&gt;                                 Implements &lt;/SPAN&gt;System.ComponentModel.IDataErrorInfo.Error
            &lt;SPAN style="COLOR: blue"&gt;Get
                If &lt;/SPAN&gt;m_validationErrors.Count &amp;gt; 0 &lt;SPAN style="COLOR: blue"&gt;Then
                    Return &lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;"Product Data is invalid"
                &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Else
                    Return Nothing
                End If
            End Get
        End Property

        Default Friend ReadOnly Property &lt;/SPAN&gt;Item(&lt;SPAN style="COLOR: blue"&gt;ByVal &lt;/SPAN&gt;columnName &lt;SPAN style="COLOR: blue"&gt;As String&lt;/SPAN&gt;) &lt;SPAN style="COLOR: blue"&gt;As String _&lt;BR&gt;                                         Implements &lt;/SPAN&gt;System.ComponentModel.IDataErrorInfo.Item
            &lt;SPAN style="COLOR: blue"&gt;Get
                If &lt;/SPAN&gt;m_validationErrors.ContainsKey(columnName) &lt;SPAN style="COLOR: blue"&gt;Then
                    Return &lt;/SPAN&gt;m_validationErrors(columnName).ToString
                &lt;SPAN style="COLOR: blue"&gt;Else
                    Return Nothing
                End If
            End Get
        End Property
#End Region

    End Class
&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;End Namespace&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P&gt;Notice that the client-side IDataErrorInfo properties are declared as Friend (internal) so that they are not serialized back up to the server. Next we need to make sure the bindings in the XAML of our ProductDetail form is set up to display the error. &lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;TextBox 
&lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt; Text&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="{&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Binding &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Path&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=ProductName, &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;&lt;STRONG&gt;ValidatesOnDataErrors&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&lt;STRONG&gt;=True&lt;/STRONG&gt;}"
&lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt; Height&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="25" &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Name&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="TextBox1" &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Width&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="180" &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Margin&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="3" &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;HorizontalAlignment&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="Left" /&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;You can also add a validation ErrorTemplate if you like. &lt;A href="http://blogs.msdn.com/bethmassi/archive/2008/06/27/displaying-data-validation-messages-in-wpf.aspx" target=_blank mce_href="http://blogs.msdn.com/bethmassi/archive/2008/06/27/displaying-data-validation-messages-in-wpf.aspx"&gt;I've shown this validation technique with WPF here before&lt;/A&gt;. So when we don't enter the ProductName on a product we can display the problem to the user right away without bothering our data service:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/ADO.NETDataServicesInterceptingQueriesan_C65B/AstoriaChange2_2.jpg" mce_href="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/ADO.NETDataServicesInterceptingQueriesan_C65B/AstoriaChange2_2.jpg"&gt;&lt;IMG height=352 alt=AstoriaChange2 src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/ADO.NETDataServicesInterceptingQueriesan_C65B/AstoriaChange2_thumb.jpg" width=488 border=0 mce_src="http://blogs.msdn.com/blogfiles/bethmassi/WindowsLiveWriter/ADO.NETDataServicesInterceptingQueriesan_C65B/AstoriaChange2_thumb.jpg"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Check out the &lt;A href="http://code.msdn.microsoft.com/astoriawpf" target=_blank&gt;updated sample on Code Galley&lt;/A&gt;, in there I also implement IEditableObject so that users can cancel out of editing of the products.&lt;/P&gt;
&lt;P&gt;However, the fact that we have to put rules in two locations in our code is a total drag. If we could type share the entity partial classes on the server and the client then we could write this code in one place and run it in both the client and the server. This is why if you have complex business rules you're probably better off creating your own DataContracts and implementing your own WCF services. However, applications like this that have simple validation and heavy CRUD requirements make it a perfect candidate to use ADO.NET Data Services.&lt;/P&gt;
&lt;P&gt;Next post I'll show how we can query and edit tabular data inside of an Excel client and post changes back to the data service. &lt;/P&gt;
&lt;P&gt;Enjoy!&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9362890" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Visual+Basic/default.aspx">Visual Basic</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/WPF/default.aspx">WPF</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/LINQ/default.aspx">LINQ</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/DevCenter/default.aspx">DevCenter</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Article/default.aspx">Article</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Data/default.aspx">Data</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/N-tier/default.aspx">N-tier</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/Entity+Framework/default.aspx">Entity Framework</category><category domain="http://blogs.msdn.com/bethmassi/archive/tags/ADO.NET+Data+Services/default.aspx">ADO.NET Data Services</category></item></channel></rss>