Programming Entity Framework, 1st Edition

3 downloads 201 Views 25MB Size Report
Method Based Syntax Queries for LINQ and Entity SQL . ..... This PDF is made available for personal use only during the relevant subscription term, subject to ...
Programming Entity Framework, 1st Edition

Table of Contents Copyright .................................................................................................... 1 Introducing the ADO.NET Entity Framework ............................................. 1 Program against a model, not against the database ...................................................................................................................... 2 Entity Data Model: A Client Side Data Model ............................................................................................................................... 3 The Entity in Entity Framework .................................................................................................................................................... 6 Choose your back end .................................................................................................................................................................... 8 Entity Framework Features ......................................................................................................................................................... 10 Entity Framework in Web Services .............................................................................................................................................. 14 What about ADO.NET DataSets and LINQ to SQL? ................................................................................................................... 14 Entity Framework Pain Points ..................................................................................................................................................... 16 Programming Entity Framework ................................................................................................................................................. 18

Exploring the Entity Data Model ............................................................... 19 Why use an Entity Data Model? ................................................................................................................................................... 19 Entity Framework and the Entity Data Model ............................................................................................................................ 20 Your First Entity Data Model ...................................................................................................................................................... 20 The Entity Data Model in the Designer Window ........................................................................................................................ 23 Entity Properties .......................................................................................................................................................................... 25 The naked model: Inspecting the model's XML .......................................................................................................................... 28 A less daunting model view ......................................................................................................................................................... 28 The three parts of the model ........................................................................................................................................................ 29 CSDL: The Conceptual Schema .................................................................................................................................................... 31 SSDL – The Store Schema ........................................................................................................................................................... 43 MSL – The Mappings ................................................................................................................................................................... 48 Database Views in the Entity Data Model ................................................................................................................................... 52 From EDM to Classes: Code Generation ..................................................................................................................................... 53 Summary ...................................................................................................................................................................................... 53

Foundations of EDM Queries .................................................................... 54 Query the Model not the database ............................................................................................................................................... 54 Your first EDM query ................................................................................................................................................................... 55 LINQ to Entities ............................................................................................................................................................................ 61 Creating ObjectQueries Directly .................................................................................................................................................. 63 Method Based Syntax Queries for LINQ and Entity SQL ........................................................................................................... 67 The Shortest Entity SQL Query .................................................................................................................................................... 72 Combing LINQ Methods and Query Builder Methods ................................................................................................................ 72 EntityClient – the lowest level method for returning streamed data through EDM queries ..................................................... 73 Translation to Database queries ................................................................................................................................................... 77 Avoid Inadvertent Query Execution ............................................................................................................................................ 79 Chapter Summary ........................................................................................................................................................................ 80

More Querying the EDM .......................................................................... 80 Same Model, Friendlier Name ..................................................................................................................................................... 81 Projections in Queries .................................................................................................................................................................. 82 Projections in Entity SQL ............................................................................................................................................................ 88 Querying Across Associations ...................................................................................................................................................... 91 Joins and Nested Queries ........................................................................................................................................................... 102 Grouping ..................................................................................................................................................................................... 107 Shaped data returned by queries ................................................................................................................................................ 112 Deferred Loading and Eager Loading queries ............................................................................................................................ 117 Retrieving a single entity ............................................................................................................................................................ 124 Entity SQL's Wrapped & Unwrapped results ............................................................................................................................. 125 Summary .................................................................................................................................................................................... 130

Basics of Stored Procedures in the EDM ................................................. 130 Saving Entity Changes back to the database .............................................................................................................................. 130 Updating the model .................................................................................................................................................................... 131 The New Functions in the Model ............................................................................................................................................... 133 Implementing the Functions ...................................................................................................................................................... 136

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

What about the READ Stored Procedure? ................................................................................................................................. 142 The EDM Designer's Model Browser ......................................................................................................................................... 143 Map the last of the four functions — CustomersbyState. .......................................................................................................... 145 Chapter Summary ....................................................................................................................................................................... 147

Tuning up the Model ............................................................................... 147 The BreakAway Geek Adventures Business Model .................................................................................................................... 147 Create a Class Library Project to host an Entity Data Model .................................................................................................... 149 Inspect and clean up the new model .......................................................................................................................................... 151 Cleaning up the Navigation Property Names ............................................................................................................................. 153 Mapping a few Stored Procedures .............................................................................................................................................. 156 Many-to-Many Relationships .................................................................................................................................................... 160 Building the BreakAwayModel Project ...................................................................................................................................... 162 Chapter Summary ....................................................................................................................................................................... 166

Data Binding EF in Windows Apps: Part 1 ............................................... 166 Create a Windows Forms Application to use the BreakAway Model ........................................................................................ 167 Use WinForms DataSources to help with Data Binding ........................................................................................................... 169 Adding the Reservations Entity Collection to the form ............................................................................................................. 178 Editing Customers ...................................................................................................................................................................... 181 Editing the Navigation Properties (and trimming down the query) ......................................................................................... 183 Adding new Customers .............................................................................................................................................................. 188 Data binding with WPF Applications ......................................................................................................................................... 191 Create the new project ................................................................................................................................................................ 193 XAML's Role in Data binding ..................................................................................................................................................... 195 Selecting a Trip and Seeing its Details ....................................................................................................................................... 197 Adding the Activities EntityCollection to the mix ..................................................................................................................... 200 Editing Trips and their related data .......................................................................................................................................... 203 Adding Items to the Activities Entity Collection ....................................................................................................................... 205 The Last Task! Add new Trips to the Catalog ............................................................................................................................ 207 Chapter Summary ...................................................................................................................................................................... 210

Object Services ........................................................................................ 211 Where Do Object Services Fit into the Framework? .................................................................................................................. 211 Query Processing ........................................................................................................................................................................ 212 Object Materialization ............................................................................................................................................................... 224 Object Management ................................................................................................................................................................... 225 State Management and ObjectStateEntry .................................................................................................................................. 231 Relationship Management ......................................................................................................................................................... 234 Sending Changes Back to the Database ..................................................................................................................................... 240 Additional Features .................................................................................................................................................................... 245 Chapter Summary ...................................................................................................................................................................... 250

Customizing Entities .............................................................................. 250 Partial Classes in the Entity Framework .................................................................................................................................... 251 Partial Methods in Entity Framework ....................................................................................................................................... 252 Available Event Handlers ........................................................................................................................................................... 257 Other opportunities in Partial Classes ....................................................................................................................................... 264 Overload Context and Entity Methods ...................................................................................................................................... 267 Partial Classes are for more than just overriding existing methods and events ...................................................................... 269 Custom Code Generation ........................................................................................................................................................... 269 Create Common Methods or Properties for all Entities ............................................................................................................ 269 Chapter Summary ...................................................................................................................................................................... 270

ASP.NET EntityDataSource Control ....................................................... 270 The Entity Data Source Control ................................................................................................................................................. 271 Start with a Hello World Web App ............................................................................................................................................. 271 How the EntityDataSource creates a query ............................................................................................................................... 276 EntityDataSource and Related Data .......................................................................................................................................... 277 EntityDataSource and Database Hits ........................................................................................................................................ 284 EntityDataSource and Hierarchical Data .................................................................................................................................. 285 Understanding the EntityDataSource control ........................................................................................................................... 297 Summary .................................................................................................................................................................................... 302

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Advanced Entity Data Models ................................................................. 303 Entity Data Model and the EDM Designer ................................................................................................................................ 303 Inheritance in the EDM ............................................................................................................................................................. 304 Table per Type Inheritance (TPT) ............................................................................................................................................. 304 Entity Splitting ........................................................................................................................................................................... 318 Conditional Mapping ................................................................................................................................................................. 324 Table per Hierarchy Inheritance (TPH) .................................................................................................................................... 329 Complex Types ........................................................................................................................................................................... 335 QueryView for Read-Only Entities ............................................................................................................................................ 346 Additional Mapping Possibilities ............................................................................................................................................... 354 Chapter Summary ...................................................................................................................................................................... 355

Implementing Stored Procedures: Beyond the Basics ............................. 356 Are Stored Procedures Second Class Citizens in the Entity Framework? ................................................................................ 356 Does the Procedure Line up with an Entity? ............................................................................................................................. 357 Stored Procedures for Querying ................................................................................................................................................. 357 Adding Native Queries into the model ...................................................................................................................................... 364 Adding Native Views to the Model ............................................................................................................................................. 365 Commands that Affect the Persisted Database ......................................................................................................................... 376 Writing Queries against the functions ....................................................................................................................................... 381 Insert/Update/Delete mapping to Types within an Inheritance structure .............................................................................. 381 Chapter Summary ...................................................................................................................................................................... 382

Entities in Web and WCF Services .......................................................... 383 Building a Client that is Ignorant of the Entity Framework ..................................................................................................... 383 Building the ASMX Web Service and Client .............................................................................................................................. 385 The Client Application ................................................................................................................................................................ 397 Using Entity Framework with WCF Services ............................................................................................................................ 405 Summary .................................................................................................................................................................................... 434

Relationships and Associations .............................................................. 434 Associations in the EDM Designer ............................................................................................................................................ 435 How did the wizard create the association set? ......................................................................................................................... 436 Associations are only a piece of the Relationship puzzle .......................................................................................................... 438 The "Platinum Rule" about Object Graphs ................................................................................................................................ 439 Relationship Span ...................................................................................................................................................................... 440 Relationships are a two-way affair ............................................................................................................................................ 440 Relationships are First Class Citizens ........................................................................................................................................ 441 Navigation Properties in Entity Objects .................................................................................................................................... 444 Entity and EntityReference Properties ...................................................................................................................................... 445 EntityCollections ........................................................................................................................................................................ 447 Creating Relationships Between Entities .................................................................................................................................. 448 Moving an Entity to a new Graph .............................................................................................................................................. 458 iEnumerables & CreateSourceQuery to Enhance Deferred Loading ........................................................................................ 459 Getting a Foreign Key value ....................................................................................................................................................... 460 Associations Impact the Native Query ...................................................................................................................................... 462 Referential Integrity and Constraints ........................................................................................................................................ 463 Deletes and Cascading deletes ................................................................................................................................................... 466 Chapter Summary ...................................................................................................................................................................... 468

Making it Real: Connections, Transactions, Performance and more ...... 469 EntityConnection and Database Connections in the Entity Framework .................................................................................. 469 Entity Framework and Transactions ......................................................................................................................................... 477 Security ....................................................................................................................................................................................... 484 Performance ............................................................................................................................................................................... 488 Entities in Multi-Threaded Applications ................................................................................................................................... 503 Chapter Summary ...................................................................................................................................................................... 509

Take Control of Objects with ObjectStateManager and Metadata Workspace ................................................................................................................ 509 ObjectStateManager Manages ObjectStateEntries .................................................................................................................... 510 Getting an ObjectStateManager and its Entries ........................................................................................................................ 512 CurrentValues and OriginalValues ............................................................................................................................................. 517

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Building the ObjectStateEntry Visualizer .................................................................................................................................. 520 ObjectStateManager and SavingChanges .................................................................................................................................. 535 The MetadataWorkspace API .................................................................................................................................................... 538 Creating Entity Objects without Entity Classes ......................................................................................................................... 553 Combining Reflection, MetadataWorkspace and ObjectStateManager to dynamically create entities and build graphs ...... 556

Handling Entity Framework Exceptions ................................................. 560 General Exception Handling in .NET ........................................................................................................................................ 561 Preparing for Exceptions in Entity Framework code ................................................................................................................ 561 Problems caused by EntityConnectionString ............................................................................................................................ 563 Query Compilation Exceptions .................................................................................................................................................. 565 SaveChanges Command Execution Exceptions ........................................................................................................................ 568 ObjectStateEntries returned by Object Services Exceptions ..................................................................................................... 571 InvalidOperationExceptions ...................................................................................................................................................... 572 Problems caused when data is being concurrently edited by multiple parties ......................................................................... 573 Approaches to handling Concurrency conflicts ......................................................................................................................... 573 Optimistic Concurrency Options ............................................................................................................................................... 574 Setting up Optimistic Concurrency in Entity Framework ......................................................................................................... 577 Concurrency and EntityReference Navigation Properties ........................................................................................................ 581 Concurrency and Inherited Types .............................................................................................................................................. 581 Concurrency Checks and Stored procedures ............................................................................................................................. 582 Handling OptimisticConcurrencyExceptions ............................................................................................................................ 584 ObjectContext.Refresh ............................................................................................................................................................... 584 Low-Level Concurrency Exception Handling ............................................................................................................................ 596 Exceptions and Your Own Transactions ................................................................................................................................... 602 Chapter Summary ...................................................................................................................................................................... 604

Custom Classes in the Entity Framework ............................................... 605 Mapping Classes to the Entity Data Model ............................................................................................................................... 605 Implementing the IPOCO Interfaces ......................................................................................................................................... 615 Custom Class Assemblies and the Entity Data Model files ....................................................................................................... 622 Chapter Summary ...................................................................................................................................................................... 623

Considerations for using EF in Client Side Application Layers ............... 623 A Long Running ObjectContext ................................................................................................................................................. 625 New Ways to Perform Old Tricks .............................................................................................................................................. 625 Business Layer Class Primary Elements ................................................................................................................................... 628 A Master-Detail Data Entry Form ............................................................................................................................................. 629 The Customer List ...................................................................................................................................................................... 630 Returning a Customer Graph to the User Interface .................................................................................................................. 632 Supplying lists for the various drop downs ............................................................................................................................... 636 Generic Methods to return random entities .............................................................................................................................. 639 Saving Changes .......................................................................................................................................................................... 640 Rolling Back User Changes ........................................................................................................................................................ 642 Data binding in a Master Detail form and considerations for the business layer .................................................................... 646 Chapter Summary ...................................................................................................................................................................... 653

Considerations for implementing Layers in ASP.NET Applications ........ 654 Web Page Life Cycle ................................................................................................................................................................... 654 EntityObjects and Read-only web pages .................................................................................................................................... 657 Updating Entities in an ASP.NET Application .......................................................................................................................... 660 Evaluating ASP.NET's State Solutions against Entity Framework ........................................................................................... 661 ASP.NET's ObjectDataSource control ....................................................................................................................................... 665 The BreakAway Customer Management Web Page .................................................................................................................. 668 Using the Provider classes with the ObjectDataSources ........................................................................................................... 679 What about using Object Graphs in the Business Layer? ......................................................................................................... 687 Chapter Summary ...................................................................................................................................................................... 688

A Smarter WCF Service to Work with Entities ........................................ 689 Will your client agree to your data contract? ............................................................................................................................ 690 Recipe for a WCF Service that can update graphs ..................................................................................................................... 691 The Service Interface ................................................................................................................................................................. 698 Service Operation Implementation ........................................................................................................................................... 699 Implementing the Client ............................................................................................................................................................ 710

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Testing it all out with a simple Console App .............................................................................................................................. 717 Chapter Summary ....................................................................................................................................................................... 719

Entity Framework Today and Tomorrow ................................................ 720 What about Building Reports with Entity Framework? ............................................................................................................ 720 Extensions, Samples and Solutions from Microsoft .................................................................................................................. 722 Entity Framework v.Next ........................................................................................................................................................... 723

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 1

Return to Table of Contents

Copyright Copyright © Julia Lerman, 2009. All rights reserved. Published by O'Reilly Media, Inc. (1005 Gravenstein Highway North, Sebastopol, CA, 95472) O'Reilly books may be purchased for educational, business, or sales promotional use. Online editions are also available for most titles (http://safari.oreilly.com). For more information, contact our corporate/institutional sales department: (800) 998-9938 or [email protected].

Licensed by Dave Olsen

Nutshell Handbook, the Nutshell Handbook logo, and the O'Reilly logo are registered trademarks of O'Reilly Media, Inc. The vulpine phalanger and related trade dress are trademarks of O'Reilly Media, Inc. Many of the designations uses by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in this book, and O'Reilly Media, Inc. was aware of a trademark claim, the designations have been printed in caps or initial caps. While every precaution has been taken in the preparation of this book, the publisher and authors assume no responsibility for errors or omissions, or for damages resulting from the use of the information contained herein.

Chapter 1. Introducing the ADO.NET Entity Framework Developers spend way too much time writing repetitive data access code and focusing on the schema of their database. It's time to stop the madness. The ADO.NET Entity Framework is a new Data Access platform from Microsoft for writing .NET Applications. It was released in July 2008 as part of the Visual Studio Service Pack 1 and .NET 3.5 Service Pack 1 package, two years after it was first announced at Microsoft's TechEd 2006 Conference. While the existing data access features remain in ADO.NET, this new framework is based on Microsoft's core data access strategy going forward and therefore Entity Framework will receive the bulk of the innovation and resources from Microsoft's Data Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 2

Return to Table of Contents

Programmability team. It's an important technology for Microsoft and therefore one that you should not ignore. Why do we need a new data access technology? After many years of forcing developers to switch from DAO to RDO to ADO and then to ADO.NET, with ADO.NET it seemed that Microsoft had finally settled on a tool that we could make a big investment in. As Visual Studio and the .NET Framework have evolved, ADO.NET has evolved by enhancement and addition but has remained backward compatible all along. Our investment was safe. And it remains safe. Entity Framework is another enhancement to ADO.NET, giving developers another mechanism for accessing data and working with the results in addition to DataReaders and DataSets. One of the core benefits of Entity Framework is that you don't have to be concerned with the structure of your database. All of your data access and storage is done against a conceptual data model that reflects your own business objects.

1.1. Program against a model, not against the database With DataReaders and many other Data Access technologies the developer spends a lot of time getting data from the database, reading through the results and picking out bits of data and pushing them into your business classes. With the Entity Framework, you are not querying against the schema of the database but against a schema which reflects our own business model. As the data is retrieved, you are not forced to reason out the columns and rows and push them into objects, they are returned as objects. When it's time to save changes back to the database, you only have to save those objects. Entity Framework will do the necessary work to translate your objects back into the rows and columns of the relational store. Entity Framework does this part of the job for you, similar to the way an Object Relational Mapping tool works. Entity Framework uses a model called an Entity Data Model which evolved from Entity Relationship Modeling, a concept that has been used in database development for many years.

Entity Data Model's Roots Entity Framework evolved from a methodology called Entity Relationship Modeling (ERM) that has been trapped on whiteboards for over thirty years. ERM defines a schema of entities and their relationships with one another. Entities are not the same as objects. Entities define the schema of an object but not its behavior. So it's something like the schema of a table in your database except that it describes the schema of your business objects. We have drawn Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 3

Return to Table of Contents

these ERMs for years to help us figure out how to transpose the structured tabular data of our databases into the structure of our objects. No mention of ERM is complete without a nod to Dr. Peter Chen who is credited with the first definitive paper on Entity Relationship Modeling in 1976. From Whiteboard to Bits and Bytes With a host of database gurus in its ranks, Microsoft Research began devising a way to automate the process of bridging a conceptual model to the database schema. And it needed to be a two-way street so that we can retrieve data from the database into our entities and persist changes back into the database. In June 2006, Microsoft Research published its first paper on the Entity Data Model, its answer to Entity Relationship Modeling. The paper's authors include database legend, Jim Gray, who tragically disappeared while sailing off of the coast of San Francisco Bay in 2007.

1.2. Entity Data Model: A Client Side Data Model An EDM is a client side data model and it is the core of the Entity Framework. It is not the same as the database model; that belongs to the database. The data model in the application describes the structure of your business objects. It's as if you were given permission to restructure the database tables and views in your enterprise's database so that it the tables and relationships looked more like your business domain rather than the normalized schema that is designed by database administrators. Figure 1-1 shows the schema of a typical set of tables in a database. PersonDetails provides additional information about a Person that the DBA has chosen to put into a separate table for the sake of scalability. SalesPerson is a table that is used to provide additional information for those people who are salespeople. Figure 1-1. Schema of normalized database tables

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 4

Return to Table of Contents

When working with this data from your application, your queries will be full of inner joins and outer joins in order to access the additional data about Person records. Or you will access a variety of pre-defined stored procedures and views which might each require a different set of parameters and return data that is shaped in a variety of ways. A TSQL query to retrieve a set of SalesPerson records along with their personal details would look something like SELECT FROM

SalesPerson.*, PersonalDetails.*, Person.* Person INNER JOIN PersonalDetails ON Person.PersonID = PersonalDetails.PersonID INNER JOIN SalesPerson ON Person.PersonID = SalesPerson.PersonID

Imagine that a particular application could have its own view of what you wish the database looked like. Figure 1-2 reshapes the schema. Figure 1-2. Person data shaped to match your business objects.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 5

Return to Table of Contents

All of the fields from PersonDetails are now part of Person. And SalesPerson is doing something that is not even possible in a database; it derives from Person, just as you would in an object model. Now imagine that you can write a LINQ query that looks like this: from p in People.OfType select p

NOTE

LINQ only exists in C# and Visual Basic languages. With Entity Framework there is another way to express queries which allows you not only to use other languages, but provides additional benefits that you can take advantage as necessary. It's called Entity SQL and you will learn much more about Entity SQL and LINQ to Entities in Chapter 3 and Chapter 4. In return you will have a set of SalesPerson objects with all of the properties defined by this model. Figure 1-3. The SalesPerson object

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 6

Return to Table of Contents

This is the crux of how Entity Framework can remove the pain of having not only to interact with the database, but having to translate the tabular data into objects.

1.3. The Entity in Entity Framework The items described in the Entity Data Model are called entities. The objects that are returned are based on these entities are Entity Objects. They differ from typical domain objects in that they have properties but no behavior outside of methods to enable change tracking. Figure 1-4 shows the class diagram for both of the classes that get automatically generated from the model. Each class as a factory method and methods that are used to notify the Entity Framework if a property has changed. Figure 1-4. Class Diagrams for the Person and SalesPerson entities

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 7

Return to Table of Contents

You can add business logic to the generated classes, pull the results into you own business objects or even link your business objects to the Entity Data Model and remove the generated classes. But by definition, the entities only describe their schema. In addition to being able to reshape the entities in the data model, you can define relationships between entities. Figure 1-5 adds a Customer entity (also deriving from person) and an Order entity to the model. Notice the relationship lines between SalesPerson and Order, showing a One to Many relationship between them. There is also a One to Many relationship between Customers and Orders.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 8

Return to Table of Contents

Figure 1-5. SalesPerson and Customer entities each have a relationship to Order entities.

When you write queries against this version of the model, you don't need to use JOINS. The model provides navigation between the entities. This LINQ to Entities query retrieves Order information along with information about the customer. It navigates into the Customer property of the Order to get the FirstName and LastName of the Customer. from o in context.Orders select new {o.OrderID,o.OrderNumber,o.Customer.FirstName,o.Customer.LastName}

Once that data is in memory you can navigate through the objects and their properties, myOrder.Customer.LastName, just as readily. Entity Framework also lets you retrieve graphs which means that you can return shaped data such as a Customer with all of its Orders already attached. These are some of the huge benefits to querying against a data model rather than directly against the database.

1.4. Choose your back end You may have noticed that there has been no mention of the actual data store that owns the data being queried. The model doesn't have any knowledge of the data store – what type of database it even is much less what the schema is. And it doesn't need to. The database you choose as your back end will have no impact on your model or your code. Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 9

Return to Table of Contents

Entity Framework communicates with the same ADO.NET Data providers that are already used by ADO.NET; but with a caveat. The provider must be updated to support the Entity Framework. The provider takes care of reshaping Entity Framework's queries and commands into native queries and commands. All you need to do is identify the provider and a database connection string so that Entity Framework can get to the database. This means that if you need to write applications against a number of different databases, you won't have to learn the ins and outs of each database. You can write queries with Entity Framework's syntax (either LINQ to Entities or Entity SQL) and never have to worry about the differences between the databases. If you need to take advantage of functions or operators that are particular to a database, Entity SQL allows you to do that as well.

NOTE

You may notice the use of the term "data store" rather than always referring to the database. While EF currently will be about working with databases, Microsoft's vision is to work with any relational store, for example an XML file with a known schema.

1.4.1. Available Providers Microsoft's SqlClient API that is included with Visual Studio 2008 SP1 supports the Entity Framework. It will allow you to use SQL Server 2000, 2005 and 2008. You can use the full or Express versions of SQL Server 2005 and 2008 and the full version of SQL Server 2000. SQL Server CE Version 3.5 supports EF as well in the System.Data.SqlServerCe.3.5 API. At the time of writing this book there are already a host of other providers available and more on their way that will allow you to use Oracle, IBM databases, SQLAnywhere, MySQL, SQLite, VistaDB and many other databases. The providers are being written not only by the database vendors but by third party vendors as well.

NOTE

On the resources page of the book's website, you can find a list of provider APIs that support the Entity Framework.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 10

Return to Table of Contents

1.4.2. Access and ODBC A provider that supports Entity Framework needs to have specific knowledge about the type of database it is connecting to. It needs to be aware of the available functions and operators for the database as well as the proper syntax for native queries ODBC providers provide generic access to a variety of databases including Access and cannot furnish the necessary database particulars to act as a provider for Entity Framework. Therefore ODBC is not a valid provider for Entity Framework. Unless someone creates a provider specifically for Access you won't be able to use it with Entity Framework applications. Microsoft does not have plans to build an Access provider because the demand is too low.

1.5. Entity Framework Features In addition to the Entity Data Model, Entity Framework provides a set of .NET APIs that let you write .NET applications using the EDM. It also includes a set of design tools for designing the model. Following is a list of Entity Framework's key features.

1.5.1. Entity Data Model While the Entity Framework is designed to let you work directly with the classes from the Entity Data Model, it still needs to interact with the database. The conceptual data model described by the EDM is stored in an XML file whose schema identifies the Entities, their properties. Behind the conceptual schema described in the Entity Data Model is another pair of schema files that map your data model back to the database. One is an XML file that describes your database and the other is a file that provides the mapping between your conceptual model and the database. During query execution and command execution (for updates), Entity Framework figures out how to turn a query or command that is expressed in terms of the data model into one that is expressed in terms of your database. When data is returned from the database, it does the job of shaping the database results into the entities and further materializing objects from those results.

1.5.2. Entity Data Model Design Tools The screenshots in Figure 1-2 and Figure 1-3 are taken from the Entity Data Model Designer. It is part of Visual Studio and provides you with a way to work visually with the model rather than tangle with the XML. You will work with the designer right away in Chapter 2 and learn how to use it to do some more advanced modeling, such as Inheritance, in Chapter 11. You will also learn about the designer's limitations, such as the fact that it does not support all of the features of the Entity Data Model. With some of the less frequently used EDM features, you'll have to tangle with the XML after all. In Chapter 2 you will get a look at the XML and how it relates to what you see in the designer so that Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 11

Return to Table of Contents

when it comes time to tangle in Chapter 11, you'll have some familiarity with the raw schema files. The designer also allows you to map stored procedures to entities which you'll learn about in Chapter 5. Unfortunately the stored procedure support in the designer has its limitations as well, so Chapter 11 will show you how to achieve what can't be done with the designer. Another notable feature of the designer is that it will let you update the model from the database to add additional database objects that you either did not need earlier or that have been added to the database since you created the model.

1.5.2.1. The Entity Data Model Wizard One of the EDM Design tools is the Entity Data Model Wizard. It allows you to point to an existing database and create a model directly from the database so that you don't have to start from scratch. Once you have this first pass at the model, you can begin customizing the model in the designer. This version of Entity Framework is much more focused on creating models from existing databases. While it is possible to begin with an empty model, it's much more challenging to create the model first and then wire it up to a database.

NOTE

There is no tool in the current version to create a database from the model, though this is being targeted for the next version of Entity Framework which will be released as part of the next version of Visual Studio (post Visual Studio 2008).

1.5.3. Managing Objects with Object Services There are two main APIs in the Entity Framework. The one which you are likely to work with most often is referred to as Object Services. Object Services sits on top of the Entity Framework stack as shown in Figure 1-6 and provides all of functionality needed to work with the objects that are based on your entities. Object Services provides a class called EntityObject. Any class that inherits from EntityObject can be managed by Object Services. This ranges from materializing objects from the results of queries against the EDM, keeping track of changes to those objects, managing the relationships between the objects and saving changes back to the database. In between querying and updating, Object Services provides a host of capabilities to interact with the entity objects such as automatically working with a lower level of Entity

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 12

Return to Table of Contents

Framework to do all of the work necessary to make calls to the database and deal with the results. Object Services also provides the ability to serialize (both XML and binary). Figure 1-6. Object Services sits on top of the Entity Framework stack

1.5.4. Change Tracking Once an entity object has been instantiated, either as a result of data returned from a query or by instantiating a new object in code, Object Services can keep track of that object. This is the default for objects returned from queries. When Object Services manages an object it can keep track of changes made to the object's properties or its relationships to other entity objects. Object Services then uses the change tracking information when it's time to update the data. It constructs Insert, Update and Delete commands for each object that has been added, modified or deleted by comparing the original values to the current values of the entity. If you are using stored procedures in conjunction with the entities, it will pass the current values (and any original values specifically identified) to those procedures.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 13

Return to Table of Contents

1.5.5. Relationship Management Relationships are a critical piece of the Entity Data Model and in Object Services, relationships are objects. If a SalesPerson has two Orders, there will be one relationship object for his relationship with the first order and another object representing a relationship between the SalesPerson and the second order. This paradigm enables the Entity Framework to have a generic way of handling a wide variety of modeling scenarios. But as you will find, especially in Chapter 16 which dives deeply into relationships, this also requires that you have a very good understanding of how these relationships work. Some of the rules of engagement when working with related data are not very intuitive and you can write code that will raise plenty of exceptions if you break these rules. Chapter 16 will provide plenty of insight into relationships in the Entity Data Model so that you will be able to work with them expertly.

1.5.6. Databinding Entity Objects can be used in many .NET databinding scenarios. In Windows Forms, you can use entities as a data source for databound controls or as the data source for BindingSource controls, which orchestrate the binding between objects and UI controls on the form. Chapter 7 provides a well-informed walkthrough for using entities with a BindingSource controls to edit and update data. Chapter 20 focuses on separating the data access and other business logic from the user interface in order to provide better architecture for your applications. Chapter 7 also provides a walkthrough for databinding entities in Windows Presentation Foundation (WPF) applications. For ASP.NET, there is a new DataSource control called the EntityDataSource which works in a similar way to the SqlDataSource and LinqDataSource controls, allowing you to declaratively bind entity objects to your user interface. Chapter 10 is all about using the EntityDataSource. For layered applications, Chapter 21 focuses on pulling all of the data access out of the ASP.NET user interface.

1.5.7. Entity Client EntityClient is the other major API in Entity Framework. It provides the functionality necessary for working the store queries and commands (in conjunction with the database provider) connecting to the database, executing the command and retrieving the results from the store and reshaping the results to match the Entity Data Model.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 14

Return to Table of Contents

You can work with EntityClient directly or work with Object Services. Object Services sits on top of EntityClient. EntityClient is only able to perform queries and does so on behalf of Object Services. The difference is that when you work directly with EntityClient, you will get tabular results (though it can be shaped). If you are working with Object Services, it will transform the tabular data created by EntityClient into Objects. The tabular data returned by EntityClient is read only. Only with Object Services provides change tracking and the ability to save changes back to the data store.

1.6. Entity Framework in Web Services Entity Framework can be used anywhere that ADO.NET can be used including Web Services and WCF Services. Chapter 13 walks through providing services for entities and Chapter 21 revisits WCF Services using much of the knowledge you will gain in between the two chapters. At the same times that Entity Framework was released, another new technology called ADO.NET Data Services (which you may know from its original code name, Astoria) was also released. ADO.NET Data Services provides an automated way to expose data through an Entity Data Model, a LINQ to SQL model or other particular interfaces, to allow wide access to your data using HTTP commands such as GET and PUT. While this is a great way to expose your data when you don't need to have a lot of control over control how it is used, this topic won't be covered as part of this book. Here you will learn to write services that are designed more specifically for an enterprise.

1.7. What about ADO.NET DataSets and LINQ to SQL? Entity Framework is only part of the ADO.NET stack. DataSets and DataReaders are an intrinsic part of ADO.NET and LINQ to SQL was part of the original release of Visual Studio 2008.

1.7.1. DataSets DataSets and DataReaders are not going away. All of your existing investment will continue to function and you can continue to use this methodology of retrieving data and interacting with it. Entity Framework is a completely different way to retrieve and work with data. You would not integrate the two technologies for example using Entity Framework to query some data and then push it into a dataset. There would be no point. You should use one or the other. As you learn about Entity Framework you will find that that it provides a very different paradigm for accessing data. You may find that Entity Framework fits for some projects but not others where you may want to stick with DataSets.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 15

Return to Table of Contents

Entity Framework uses DataReaders as well, the EntityDataReader which inherits the same DbDataReader as SqlDataReader etc. This is what is returned by a query with EntityClient. In fact, you'll find that the code querying the EDM with EntityClient looks very similar to that which you use to query the database. It uses connections, commands, command parameters and returns a DbDataReader that can be read the same way as the others. Some ADO.NET tools that are not available with Entity Framework are Query Notification and ASP.NET's SQCacheDependency. Additionally the ADO.NET's SqlBulkCopy requires a DataReader or DataSet to stream data into the database and therefore you cannot do client side bulk loading with Entity Framework. Entity Framework does not have an equivalent to ADO.ENT's DataAdapter.BatchUpdate. When Entity Framework saves changes to the database, it can only send one command at a time. There are a few things that are easier with DataSets than with Entity Framework such as Unit Testing and change tracking across processes. You'll find a discussion of each of these below.

1.7.2. LINQ to SQL LINQ to SQL and Entity Framework look quite similar on the surface. They both provide LINQ querying against a database using a data model. Why both technologies? LINQ to SQL evolved from the LINQ project which came out of folks working with language development. Entity Framework was a project of the Data Programmability team and was focused on the Entity SQL language. By the time each technology had come along far enough that it was being shown to other team at Microsoft, it was clear that Microsoft had two great new technologies that could target different scenarios. The Entity Framework team adapted LINQ to work with Entities which confused developers even more because LINQ to Entities and LINQ to SQL look so much alike. LINQ to SQL eventually was brought into the Microsoft's Data Programmability team and in November 2008 they announced that because the technologies target the same problems, that going forward the team will focus on developing Entity Framework while maintaining and tweaking LINQ to SQL. This is not a happy situation for many developers who have made an investment in LINQ to SQL. While Microsoft has made no statements about deprecating this great and fairly new tool, they have said they will provide a migration path from LINQ to SQL to Entity Framework and will recommend Entity Framework over LINQ to SQL.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 16

Return to Table of Contents

NOTE

At the time of writing, this is a fairly recent announcement about LINQ to SQL and there's always the possibility that the outcome may change based on community feedback. The last chapter of this book will highlight some differences between Entity Framework and LINQ to SQL that be more comprehensible once you have some knowledge about Entity Framework.

1.8. Entity Framework Pain Points This book is about Entity Framework Version 1 which was released in July 2008 as part of Visual Studio 2008 Service Pack 1. Microsoft has a big vision for Entity Framework and made an explicit choice to get as much as they could into the Visual Studio 2008 SP1 release. While it is an impressive technology with enormous flexibility, there is quite a lot of functionality that is not surfaced in discoverable and easy to use ways. Additionally as with any technology, there are features that some developers find impossible to live without and will most likely wait until Version 2 to begin putting entity Framework into production. This book spends a lot of time looking into the depths of the APIs to show you how to get around some of these limitations and attempts to point out potholes, hiccups and omissions.

1.8.1. Entity Framework Designer The Designer goes a long way to give you a visual to for working with the Entity Data Model but not every capability of the EDM is easily achieved with the model and requires some work in the raw XML. While most would agree that the features you need to code manually are those which will be used less commonly, there are a few that stand out.

1.8.1.1. Stored Procedures The designer supports a narrow use of stored procedures. Using the designer, you can override Entity Framework's automatic generation of Insert, Update and Delete commands by mapping an entity to a set of stored procedures with two important rules. The first is that the stored procedure must line up with the entity. For inserts and updates that means the values for the stored procedure parameters must come from an entity's property. The second rule is that you have to override Insert, Update and Delete or none at all, so you'll need to map all three functions.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 17

Return to Table of Contents

The designer supports read queries as long as the query results map directly to an entity. If you have a query that returns random data, you will need to manually create an entity for it to map to. That's not too hard in the designer, but there's another requirement which will necessitate doing some work in the XML. Chapter 5 walks through the scenarios that the designer supports easily and Chapter 12 digs down into the scenarios that will take more effort and walks you through the necessary steps.

1.8.1.2. Unsupported EDM Types The Entity Data Model has a very rich set of modeling capabilities demonstrated in Chapter 11. But the designer does not support all of the advanced modeling techniques, requiring you to hand code them in the XML. In most cases, you can continue to work with the model in the designer even though you won't see these particular model types, though you can leverage them in your code. However there are a few model types, such as the very useful ComplexType, that when included in the XML, will make it impossible to open the model in the designer. The Designer is well aware of these limitations and at least provides an alternate view that displays a message explaining why the model can't be opened. You'll learn about this in Chapter 11.

1.8.1.3. Generate a database from the model The Entity Data Model is based on a data driven design with the assumption that there is an existing database for the model to map back to. This makes a lot of sense if you are building an application for an existing database. Domain Driven Developers prefer to create their object model first and have a database generated from that. The design tool does not support this capability. It should appear in Version 2. In the meantime developers in the community and at Microsoft are playing with a code generator called T4 _____ Templates (Text Template Transformation Toolkit) to read the model and generate SQL script files to generate database objects for you.

1.8.1.4. A host of little things As more developers use the new tools, they are finding other things that could make their lives easier and have contributed to an MSDN Forum thread titled "V2 Wish List". You can find a link to this thread on the Resources page of the book's website.

1.8.2. Challenges with change tracking distributed applications To put it mildly, there are challenges when using Entity Framework in distributed applications when it comes to the change tracking performed by Object Services. The cause of this is the change tracking information is not stored in the entities. It is maintained by a separate set of Object Services objects. When an entity is transferred across a process it loses its association with the object that contains its change tracking information. And

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 18

Return to Table of Contents

those objects which own the tracking data are not Serializable so they can't easily be shipped across to the new process along with the entities. So when the entities arrive at the new process, they have no idea if they are new or pre-existing, if they have been edited or marked for deletion. There's no way to simply use the ObjectContext's default method for saving changes to the database without doing additional work. This problem is addressed and dissected in a number of places throughout this book with a variety of coding patterns presented to help you succeed at moving entities around in distributed applications such as Services or layers ASP.NET applications. Starting with Chapter 8 which focuses on Object Services, many of the chapters throughout this book provide detailed information about change tracking and working with entities across tiers whether you use the ASP.NET Entity Data Source as in Chapter 10 or write a WCF Service with Data Transfer Objects as in Chapter 22.

1.8.3. Domain Driven Development As mentioned previously and noted in the subtitle of this book, Entity Framework Version 1's focus is data centric. Domain Driven Development begins with the model, not the database. Many developers who embrace the tenets of Domain Driven design will find Entity Framework to be too restrictive. However, some of the luminaries of this view of applications are working with the Entity Framework team to enable Version 2 to expand its capabilities so that it can be used with this approach.

1.8.4. Unit Testing While it is possible to build Unit Tests with Entity Framework classes, the fact that entities must either inherit from the EntityObject class or implement some of Object Services' key interfaces makes it impossible to decouple the entity classes from the mechanism which executes queries. Therefore, you cannot Unit Test your Entity Framework code without causing the database to be accessed. Hitting the database while performing unit tests is not a favorable option for most developers. Hopefully you wouldn't dream of testing against the live database, but even with a copy, you would need to deal with rollbacks and an assortment of other complications. Because of this, many developers have just written Entity Framework off as "untestable". One option, however, is to use a common unit testing technique called mocking. A tool such as TypeMock Isolator (http:/www.typemock.com) which can automatically mock desired objects, can help you in this quest. The next version of Entity Framework promises to enable Unit Testing capabilities.

1.9. Programming Entity Framework As you work through this book you will not only get the experience of designing EDMs and using Entity Framework to write applications, but you will dig deeply into the APIs to learn Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 19

Return to Table of Contents

how to manipulate entity objects and have granular control over much of its behavior. There is a lot of functionality that is very accessible and there's a lot of power underneath the covers. You will learn what's under the covers so that you can realize the true benefits of the Entity Framework.

Chapter 2. Exploring the Entity Data Model The Entity Data Model is the bridge between your application and your data store. It is the Entity Data Model, or EDM, that provides the definition of your conceptual schema as well as the database schema information necessary for interacting with the database and finally a mapping schema that links to two. APIs use the Entity Data Model for every interaction with the data store, whether that is to retrieve or to save data. The Entity Framework tools generate classes from the model that enable you to work with objects described by the model.

Licensed by Dave Olsen

In this chapter you will create a simple EDM using the ADO.NET Entity Data model wizard and then you will inspect the model both in the Designer and by looking at its raw XML. This chapter will stick to the basics of the model for the purpose of getting very familiar with how EDMs are structured and how the most common elements relate to one another, to your code and to the database. There is a lot of information in this chapter but because the Entity Framework is built around the EDM, you'll appreciate having a great understanding of the model as you move through this book. Chapter [X] will explore the more complex aspects of the EDM, such as different inheritance capabilities, and how to customize models so that they can better reflect your business logic.

2.1. Why use an Entity Data Model? Well designed databases can pose a problem for developers. In the data world, a database is designed for maintainability, security, efficiency and scalability. Databases are structured in ways that split the data out in a way that may be very pleasing to a good database administrator, but complicated for a developer to access. In the early 1970's, Dr. Peter Chen devised the Entity Relationship Model. This allowed software designers to define a conceptual data model that better described their business domain and then map that model back to the actual database schema. The ERM was a concept played out on whiteboards. Developers used the conceptual model as the basis for designing their business objects and then continued to write a lot of code to move data from the database to the model and back again. Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 20

Return to Table of Contents

The Entity Data Model takes this concept and moves the modeling into XML files that can be used by different programming models. The Entity Data Model contains this conceptual layer, a layer to represent the schema of the database and a layer to do the mapping between these two. The Entity Framework then provides a framework that allows developers to write .NET applications based on the Entity Data Model.

2.2. Entity Framework and the Entity Data Model The Entity Framework is a set of .NET APIs that allow you to build .NET applications using an Entity Data Model. As long as the EDM provides the conceptual schema, a representation of the database and a mapping file and at the same time, access to an Entity Framework aware ADO.NET provider for the target database, Entity Framework doesn't care what database is being targeted. It provides a common means of interacting with the database, a common query syntax and a common method for sending changes back to the database. While the Entity Framework provides a very rich set of features for developers, it's most critical functions are Automatically generates classes from the model and updates those classes dynamically any time the model changes. • Takes care of all of the database connectivity so that developers are not burdened by having to write lots of code for interacting with the database. • Provides common query syntax for querying the model, not the database, and then translates these queries into queries that the database can understand. • Provides a mechanism for tracking changes to the model's objects as they are being used in the applications and handles the updates to the database. •

Because the model's classes are dynamically generated, minor changes to the model need not have a major impact on your application. And modifying the model is much simpler than modifying your objects and then the data access code which they rely on.

2.3. Your First Entity Data Model Entity Framework revolves around the Entity Data Model and therefore the EDM is where we'll begin.

NOTE

This walkthrough will use a custom SQL Server database that you can download from the book's web site. Visual Studio 2008 provides Entity Framework

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 21

Return to Table of Contents

connectivity to SQL Server and SQL Server Express. As mentioned in Chapter 1, there are additional providers that you can install to connect to other databases such as MySQL, Oracle or VistaDB. See Appendix 2 for instructions on downloading additional providers as well as the custom databases for this book. Let's start by creating a model from the sample database, ProgrammingEFDB1. This is a simple database with only two tables, a view and some stored procedures, and therefore a great place to begin. As your understanding of Entity Data Models grows, then we can work with databases that are more realistic.

NOTE

The tools of Entity Framework Version 1 are optimized to build models from existing databases. In Version 2, the tools will provide the ability to perform modelfirst design, where you can build a model from scratch and then create a database based on the model. 1. Create a new Console Application Figure 2-1. Create a new Console Application project by choosing the template from either the Visual Basic or Visual C# project types.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 22

Return to Table of Contents

2. Add a New Item to the project. To do this, right click on the ConsoleApplication1 in the Solution Explorer, click Add, then New Item. 3. Select ADO.NET Entity Data Model from the Templates list. Figure 2-2. Select ADO.NET Entity Data Model from the Add New Item Wizard to create an Entity Data Model.

1. On the "Choose Model Contents" page, select the Generate from Database option and click Next. 2. On the "Choose Your Data Connection" page, select ProgrammingEFDB1from the drop down list of available connections and click Next.

NOTE

If you do not have ProgrammingEFDB1 set up as a database connection in Visual Studio, see Appendix 2 for setup instructions. 3. On the Choose Your Database Objects Page, check the Tables and Views nodes.

NOTE

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 23

Return to Table of Contents

In case you are hoping to also click on the check box for Stored Procedures, we'll come back to the Stored Procedures in Chapter 4. Just skip over that one for now. This will select all of the Tables and Views in the database. Alternatively, you can expand the node and select the specific objects that you want. This database has two tables (Contact and Address), one View (vOfficeAddresses) and four Stored Procedures (CustomersbyState, InsertContact, UpdateContact and DeleteContact). For this demo, you'll want the tables and the view. 4. Click Finish. 5. The new model will be displayed in the Designer window and its file will appear in the Solution Explorer. Figure 2-3. After completing the ADO.NET EDM Wizard, a new file, Model1.edmx has been added to the project and the model will be automatically opened in the Designer.

2.4. The Entity Data Model in the Designer Window This model displays a Contact entity, an Address entity and an entity representing the view. There is also a line between Contact and Address that describes a one-to-many relationship between the two. Each entity has a number of Scalar properties and the entities with relationships additionally have Navigation properties.

What to What? The two ends of relationships are often described with shortcut syntax.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 24

Return to Table of Contents

The ends can be 1 (one), * (many) or 0..1 (zero or one). This metadata is referred to as describing the multiplicity of the end. These ends are then combined to describe the relationship. For example "1:*" means "one-to-many". The classic example of this is one Order and its' many Details. "0..1:*" is "'zero or one'-to-many". An example of this is a relationship between Shippers and Orders. Many orders may be shipped by one shipper. But only one shipper can be related to an order. However, it's possible that the shipper was not assigned to the order at first; therefore it can be zero or one on the shipper end of the relationship. Scalar properties are properties whose values are literally contained in the entity. Navigation properties are pointers to related entities. The Contact entity has an Address property which will enable the application to navigate from a Contact to any Addresses related to that Contact. The Address entity has a Contact property that allows you to navigate from an Address to the single Contact associated with the Address. You may have noticed that there is no foreign key represented in either entity. How is it possible to join the entities in a relationship? As you can see in Figure 2-4, the actual Address table in the database does, in fact, have a ContactID field which is used to join the tables. The Entity Data Model replaces that foreign key with the Navigation property. Deeper in the model, the ContactID still exists. You'll see how that works a little later in the chapter. Figure 2-4. The schema of the Contact and Address tables in the database.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 25

Return to Table of Contents

In the designer, it is possible to see more information about each entity and each of its properties in the Visual Studio IDE's property window. For example, Figure 2-5 displays the properties of the Contact's FirstName property. Here it is possible to see that the FirstName is a String which cannot be null. Figure 2-5. Select the FirstName property in the model to see its properties in the Properties Window.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 26

Return to Table of Contents

2.5. Entity Properties Each entity, association and the model itself has properties. Let's change some properties of the Contact entity. Select the Contact entity to view its Properties window. Figure 2-6. View the Properties window for the Contact entity.

In the Properties window, you can see that the Entity not only has the name "Contact" which it took directly from the table name in the database, but also has an Entity Set Name. An Entity Set is a container for a collection of entities of a single type. Therefore the Entity Set named "Contact" will contain a collection of Contact entities. The wizard applied the table name to both the Name and Entity Set Name for the Contact table because it doesn't have the ability to automatically make names plural where it would make sense to do so.

2.5.1. Editing the Entity Set and Navigation Property names In order for the model to make sense, there are a few changes that you will want to make regarding plural names.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 27

Return to Table of Contents

1. Change the Entity Set Name for the Contact entity to "Contacts". 2. Change the Entity Set Name for the Address entity to "Addresses". The third change to make is for the Navigation properties. The navigation properties also automatically adopt the name of the associated entity. The Contact entity may have more more than one related address entities. Therefore it makes more sense for that Navigation property to be named "Addresses" not "Address". You can edit the Name of the Contact's Address Navigation property either by selecting that Navigation property and making the change in the Properties windowFigure7Fi or by selecting the Address Navigation property in the designer, then clicking a second time to edit it directly in the designer as shown in Figure 7. Figure 2-7. You can edit the name of a property directly in the designer by selecting the property, then clicking a second time.

Now the model is more logical and this will also make writing code against this model much friendlier.

NOTE

Cleaning up the entity, property and association names is a step that you should consider doing immediately after you create a new model with the wizard. This way as you begin to code against the model, the names of objects will be logical. Additionally, if you change these names after you have begun coding, you will have to modify your code to reflect the changes.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 28

Return to Table of Contents

While there is much more that you can do with the designer, it is time to open up the model in its raw format to really understand how it works. Be sure to save all of the work you have done already.

2.6. The naked model: Inspecting the model's XML Now it's time to get down and dirty with the Entity Data Model. Because only a portion of the model is visible in the designer, there is a lot more to learn by looking at it in its raw format. In places where the model has a counterpart in the designer, you'll see both views. By default, the file will open up in the designer; therefore you need to use a different method to open it up in its raw format. In the Solution Explorer, right click on the Model1.edmx file. From the context menu that opens, select the "Open With..." option, then choose "XML Editor" and click OK. Visual Studio cannot display the model in design view and in XML at the same time, so you will see a message asking if it's okay to close the designer view of the model. Click Yes. For those who have the common Fear-of-XML syndrome, this may look at little daunting at first. Have no fear and just follow along. Gaining an understanding of the model from this perspective will give you a big advantage when it's time to create more complex and powerful models.

2.7. A less daunting model view The EDMX file is made up of two main sections — the Runtime information and the Designer Information. The Runtime section is comprised of three sections which are the StorageModels, the Conceptual Models and the Mappings. Collapse all of the main sections of the model. You can do this quickly by right clicking in the XML and choosing Outlining, then Toggle All Outlining. Now you will see only the main node – edmx: Edmx. You can expand that until your view matches Figure 2-8. Figure 2-8. After collapsing the model then opening up the top level edmx element as well as the edmx:Runtime element, you can see the main sections of the model.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 29

Return to Table of Contents

Now you can see the main sections of the model. The edmx:Designer element is metadata that tells the designer how to position the entities. Feel free to explore that at a later time. The critical sections of the model are the Runtime ConceptualModels, StorageModels and Mappings.

2.8. The three parts of the model In the designer, you saw only the Conceptual portion of the model so far, but there are two more pieces of the EDM. These enable the Entity Framework APIs to translate between the Conceptual Model and the actual data store. The StorageModel represents the schema of the database while the Mappings describe how to get from the entities and properties of the Conceptual Model to the tables and columns described in the Storage Model. Figure 2-9. The components of an Entity Data Model

Why use the store layer to represent the data store when we have the actual data store to work with? There are a number of reasons for this piece of the model. The most important Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 30

Return to Table of Contents

reason is that this provides loose coupling to the database; not every object in the database needs to be in the model and as you will learn in Chapter {x}, it is possible to customize even the store layer to suit the needs of the model. Although the entire model is contained in a single file at design time, when the project is compiled, it will create three separate files – one for each of these sections. The conceptual layer is saved to a file with a "csdl" extension which stands for "Conceptual Schema Definition Language". The storage layer is saved to a file with an "ssdl" extension ("Store Schema Definition Language") and the mapping layer is saved to a file with the extension "msl" (Mapping Specification Language"). These are the files that are used at run time which is why they are contained in a section called "edmx:Runtime" in the model.

NOTE

By default, you will never see these physical files because they are embedded into the project assembly when the project is compiled. This is convenient for a lot of scenarios. Though it is possible to change the model's "Metadata Artifact Processing" property to "Copy to Output Directory".

A schema by any other name The three parts of the model have a variety of descriptions which you will see used in documentation, articles, training and even in this book. Here is a list of the various "nicknames". CSDL (Conceptual Schema Definition Layer) • • • •

Conceptual Layer Conceptual Schema Conceptual Model C-Side

SSDL (Store Schema Definition Layer) • • • • • •

Store/Storage Layer Store/Storage Schema Store/Storage Model Store/Storage metadata Store/Storage metadata schema S-Side

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 31

Return to Table of Contents

MSL (Mapping Schema Layer) • • •

Mapping Layer Mapping Specification C-S Side (referring to Conceptual to Store)

Each of the sections is controlled by their own schema file that lives deep within the .NET Framework files. There is a schema file that controls the CSDL, one for the MSL and yet another for the SSDL. Visual Studio's Intellisense uses these schema files to aid us when working directly with the xml, pointing out errors and presenting us with options. Compiler errors will also be displayed if the files don't fall in line with their schema rules.

Schemas for the Schemas For the very curious, you can take a look at the schema files that drive the rules for the CSDL, SSDL and MSL sections in the model. The Schema files for Visual Studio 2008 are located in C:\Program Files\Microsoft Visual Studio 9.0\Xml \Schemas. The three files to look for are System.Data.Resources.CSDLSchema.xsd, System.Data.Resources.CSMLSchema.xsd and System.Data.Resources.SSDLSchema.xsd. If you open these up in Visual Studio, they will be formatted as xml files and easy to navigate through.

2.9. CSDL: The Conceptual Schema In the XML, use the + icons to expand the ConceptualModels section until you have exposed the Schema and the Entity Container as in Figure 2-10.

NOTE

Sometimes the formatting of the XML is impacted and a particular section might lose all of its hard returns, rendering one very long line of code that is hard to decipher. You can fix this by highlighting the line, then from the Visual Studio menu, select, Edit/Advanced/Format Selection, which will make the formatting of the XML much more palatable.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 32

Return to Table of Contents

Figure 2-10. Expand the Conceptual Model, its schema and the EntityContainer inside the Schema.

Now we will walk through the exposed portion of the model to see what's what.

2.9.1. Schema element The outer element, Schema, defines the name of the Namespace for the entire model, which in this model is "ProgrammingEFDB1Model". The namespace is defined by default to have the name of the database from which model is derived plus the word Model. The schema also defines an Alias, which by default is always "Self". This is just a nickname for the model and you can name it anything you like. There is also an xmlns namespace URI, which defines the origin of Microsoft's schema file.

NOTE

You can also see and modify the model's Namespace in the Property Window of the model when it is open in the designer view.

2.9.2. EntityContainer Within the schema, there is an Entity Container that has a default name, "ProgrammingEFDB1Entities". Like the namespace, this is the pattern for the default EntityContainer name using the database name plus the word "Entities". This name can be seen and changed in the Property Window for the model when you have the model opened in the designer. The EntityContainer is a wrapper for the EntitySets and Association Sets. You'll recognize the Contacts and Addresses EntitySets which you renamed earlier. AssociationSets reference the associations between the entities. We'll come back to the AssociationSets after the Association elements have been explained. Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 33

Return to Table of Contents

As shown in Figure 2-11, the EntityContainer is the critical entry point for querying the model. It exposes the EntitySets and it is the EntitySets that you will write your queries against. The EntitySets, in turn, give you access to their entities. Figure 2-11. The Relationship of the Entity Container to its EntitySets and the Entities

2.9.3. Entity Set An Entity Set is a container for a type of entity. Its two attributes are Name and EntityType. EntityType defines which entity the Set contains using its strongly typed name. The entity's strongly typed name includes the model's namespace.

An EntitySet is sometimes referred to as a "wrapper" for an Entity because it is through the EntitySet that we have access to the individual entities when querying against the Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 34

Return to Table of Contents

model. When you begin querying in the next chapter, you will see that we use code that translates to "find some entities in the Addresses EntitySet". The model instructs your query that the type of entities returned will be Address.

NOTE

As you will learn further on in the book, the EDM allows for inherited types. Therefore your model may have a contact entity and a customer entity, where the customer is a type of contact. In this case, the Contacts EntitySet will serve as a wrapper for both the contact entities and the Customer Entities.

2.9.4. Entity Type An EntityType is a data type in the model. You have already seen a Contact entity type and an Address entity type. Expand the Address entity type which will look like Example 2-1 to get a closer look. It contains a Key element and a list of Property elements. Example 2-1. The Address Entity's XML

2.9.4.1. Key The Key element defines which of the properties make up the identity key for the entity. The Entity's key plays a critical role in the life cycle of an entity, enabling your application Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 35

Return to Table of Contents

to keep track of an entity, perform database updates and refreshes and more. You will learn more about this in later chapter when we talk about "Entity Key". In the designer, you can specify the Key in the Properties window of the entity. The key for the Address entity only uses a single property, AddressID. It is possible to have keys made up of multiple properties. These are called composite keys and are similar to composite keys in databases.

2.9.4.2. Property First take note of the properties. Not only do they have names, but they are defined by their data type and a variety of "facets" that further describe the property. The data types that define these properties are called "Simple Types". These are primitive types in the Entity Framework object model that closely line up with the data types in the .NET Framework. EF's primitive types, however, are used only to define the entity property. They do not have their own properties. They are truly simple. Most, but not all of this information can be viewed and edited in the Properties window as shown in Figure 2-12. You can also see properties in the Property window that are not shown in the XML. Figure 2-12. The Address entity with its Street1 property selected. The Street1details are shown in the Properties window.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 36

Return to Table of Contents

The Unicode, MaxLength and FixedLength properties are not surfaced in the designer. Properties that are set to their default values are not explicitly written out in the XML. This is the case for a number of the properties of Address.Street1 such as ConcurrencyMode, Default Value, Getter and Setter. The EntityKey property is not a facet of Street1 but is used to create the EntityKey element that was described above. If you look at the properties of AddressID, you'll see that its EntityKey property is True.

NOTE

You'll learn more about the Getter and Setter properties later in this chapter. Chapter 13 digs further into Concurrency and there you will learn about the ConcurrencyMode property.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 37

Return to Table of Contents

See the schema validation in action To see the schema's schema rules in action, try editing the XML manually. For example, start entering a new element inside of the Address EntityType. Intellisense will provide a list of options within the Property. Or, break something! For example, take a letter or two out of one of the elements perhaps turn EntityType into ElephantType. There will be visual clues in the XML to indicate issues, and in the Errors List there will be warnings listed about invalid elements. Don't forget to undo these changes!

2.9.4.3. NavigationProperty The Navigation Properties of the entities are tightly bound to the associations that are represented by the lines between the entites as you saw in Figure 2-3. We'll dig further into the Navigation properties after discussing the Associations further on.

2.9.5. Association Associations define the relationships between Entity Types. The Association doesn't define the relationship completely however. It defines the end points (i.e. the entities that are involved in the relationship) and their multiplicity. In the example model, there is only one association which is between the Contact and Address. It tells us that there is a relationship between the Contact entity type and the Address entity type. The name of this association was taken from the predefined relationship in the database when the wizard first created the model. Like any other element in the model, you can edit the name of the association if you prefer more readable names or if you have naming conventions that you need to follow. Let's first look at the Associations' properties in the designer view. If you are following along, close the XML and open the model back up in the designer. Figure 2-13. Figure Caption Text Goes Here

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 38

Return to Table of Contents

The association lists both ends. The first end is the Contact Entity Type, again, fully qualified using the Namespace. It is assigned a role called "Contact". The role acts as the name of an End so that it can be pointed to by elements elsewhere in the model. The End also tells us that there will only be one contact in a relationship between Contact and Address. The second end will be an Address Entity Type and there can be many addresses in this relationship. After "reading" the association, we understand that there is a one-to-many relationship between Contact and Address. A single contact might have a home address, a work address and even other addresses. However an address will only ever be associated with a single contact. In the real world, it is possible for an address to be associated with multiple people, for example family members or roommates or employees at a single organization. That would involve a many to many relationship, which will be explored in Chapter [X]. Like the entities, an association defines the name of the AssociationSet that contains this type of association. You could also make this name plural, but it is not as critical as pluralizing the EntitySet names because you won't be interacting with the AssociationSets in code.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 39

Return to Table of Contents

Example 2-2 shows the Association in the XML, which provides the same elements as you see in the Property Window. Example 2-2. The Association between Contact and Address

The OnDelete element was inferred based on a constraint in the database that tells the database that if a Contact is deleted, all of its Addresses should be deleted as well. This will get discussed in further detail later in this chapter and in even greater detail in Chapter [X] which focuses on Relationships and Associations.

2.9.6. AssociationSet Along with the EntitySets, the EntityContainer contains AssociationSets. Just as the EntitySet is a container for Entity Types, the AssociationSet is a container for an Association. Therefore it should not be a surprise to see that the Association is a container for the FK_Addresses_Contact association.

While it makes sense to have a container for an entity because you could have many contact entities to work with, how would there be a collection of Associations? When you are working with entity objects, the associations between the entities are also objects. If you have a single contact with multiple addresses in memory, then there would be one FK_Address_Contact association object for each relationship. Figure 2-14 shows two association objects that are used to define relationships between a single contact and two addresses. Figure 2-14. Figure Caption Text Goes Here

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 40

Return to Table of Contents

NOTE

Notice that the description of the AssociationSet binds each End point of the association (by referencing the Role) to the EntitySet. This now creates a thread through the model so that the APIs will be able to move through an EntitySet and discover various entities that are related to each other. When I first realized how the role was being used in teh AssociationSet metadata, something finally clicked for me and I was able to see the big picture of the model. It was almost as if the last piece of the puzzle had just been put into place and I could see the clear image for the first time. I hope I've been able to bring you there.

2.9.7. NavigationProperty Finally, we can look at the Navigation properties in the Address and Contact Entity Types. Now that the Association has been explained, the Navigation property should be much easier to comprehend. While it is easily possible for entities to have multiple NavigationProperties, in this particular model we have only one in each of the Entity Types. Error! Reference source not found. shows the Property window for th Contact Navigation Property of the Address entity. Figure 2-15. The Properties of Address' Contact Navigation Property

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 41

Return to Table of Contents

The Navigation Property is just another property in the Entity.. When working with the Address in code, this is how it will appear — as just another property. While the other properties are referred to as "scalar" properties, meaning that the property is a value, the Navigation property is a property that describes how to navigate to a related entity. A critical property of the Navigation is it's Association property. This tells the Navigation which Association in the model contains the necessary information about how to navigate to the related entity (or entities in the case of Contact.Addresses). As explained above, that Association defines the relationship between the Address and Contact Entity Types. The FromRole and ToRole attributes tell the Entity Framework that when looking at this association, it needs to navigate from the End point named Address to the EndPoint called Contact. This in turn, will allow you to navigate from the Address entity type to its associated Contact Entity Type in your code. Like the entities, the designer shows some properties that are used for code generation: Getter, Setter and Documentation. Additionally, there are some read-only properties in the designer's property window that are there only to help you better understand teh navigation. These are Multiplicity and Return Type. The Contact's multiplicity is one and when you navigate to Address.Contact, what you will get is an instance of a contact (a single Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 42

Return to Table of Contents

contact object). A navigation property that returns a single object is referred to as a Navigation Reference. When looking at this same Navigation property in the XML, you will not see these read only properties and because the Setter, Getter and Documentation are using the defaults, they are not listed either.

2.9.8. Navigation Properties that Return Collections The Contact property of Address returns a single instance of a contact. What about the Addresses property of a Contact entity? The Addresses property is shown in Figure 2-16. Figure 2-16. The Addresses Navigation Property

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 43

Return to Table of Contents

When navigating from Contact to Addresses, the Addresses end point defined in the "FK_Address_Contact" Association, has a multiplicity of "*" (many). Therefore the Entity Framework expects a collection inside the Addresses property. In the designer, the Return Type property of Addresses is Collection of Addresses. This type of navigation property is called a Navigation Collection. In code, the Contact.Addresses property will return a collection of Address entities, even if there is only one Address in the collection. If there are no addresses for a particular person, the collection will be empty. The collection that is exposed in the Addresses Navigation property is not a collection from the System.Collections namespace but an EntityCollection. EntityCollection is a completely unique class in the Entity Framework. So while it is simpler to say "a collection of addresses", it's important to pay attention when you are working with an EntityCollection versus a type that inherits from System.Collections.ICollection as they are not interchangeable.

2.9.9. Where are the Foreign Keys? Remember that the ContactID column in the Addresses table in the database does not exist in the Address Entity Type. Where did it go and how is the navigation possible with the missing foreign key? This is the last mystery to be solved about Navigation Properties and will be answered when we dig into the Mapping Layer portion of the EDM. There is a lot more to learn about CSDLs, but continuing with our simple model, it's time to look at another piece of the model, the Storage Layer, or SSDL, which you will need to understand before you can get to the Mapping layer. It is important to note that in this simple model, the conceptual layer has not been customized. It mirrors the schema of the database which is a very good place to begin learning about Entity Data Models. Further on, you will learn about customized models and begin to leverage the real power of the EDM.

2.10. SSDL – The Store Schema

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 44

Return to Table of Contents

The StorageModels section of the model is a schematic representation of the data store. The elements of this file are similar to those of the CSDL file. Figure 2-17 below shows the complete SSDL from the ProgrammingEFDB1 model although not every section is expanded.

What if the database changes? The EDM Design tools include a feature that allows you to update the model from the database. This function is available in the context menu that you get when right clicking in the EDM Designer. You'll work with Update Model in Chapter 4 to bring database's Stored Procedures into the model.

Figure 2-17. Expand the StorageModels section to being exploring the Store layer of the model.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 45

Return to Table of Contents

For consistency, the tables and columns are called EntityTypes and Properties. Be aware that you will frequently see these be l referred to as tables and columns in documentation and even in the visual tools. While we are working with a relational database in this model, future versions of EF will allow us to have different types of data stores, for example an XML file. SSDL therefore uses terminology that will work for whatever type of relational data we may throw at it in the future. Note the following differences from the CSDL:

2.10.1. Schema Element 1. The Namespace has ".Store" appended to it, so that it's clear that this schema is for the data store, not the conceptual layer of the model. 2. There is a ProviderManifestToken attribute. The value in the example represents the version number of SQL Server 2008, which is the database being used for this model. This bit of information is used by EF and is required. The values are determined by the provider that you are using (in this case SqlClient) and what values it exposes for the token.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 46

Return to Table of Contents

3. The xmlns namespace is a folder within the xmlns namespace used for the CSDL. Again, this particular parameter is static.

2.10.2. EntityContainer The name of the EntityContainer is "dbo", which was derived from the database schema name.

2.10.3. EntityType 1. The Entity Type names are the actual names of the tables in the database. 2. The property types are the provider data types, in this case, SQL Server data types 3. The identity columns are attributed with StoreGeneratedPattern="Identity" meaning that the database will generate the values for these columns and they happen to be Identity columns. The other options are "None" (the default) or "Computed".

2.10.4. Association and AssociationSet In Example 2-3, the Association and AssociationSet have been expanded and you can see a pattern familiar to their CSDL counterparts. The Association's description displays how the database defines the Primary Key / Foreign Key relationship between Contact and Address. Example 2-3. SSDL Association and AssociationSet

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 47

Return to Table of Contents

The generic term, Association, in the SSDL is referring to the PrimaryKey/Foreign Key relationship defined in the database. Figure 2-18 shows the origin of this in the database's Address table. Figure 2-18. The PKFK relationship between Address and Contact in the database.

The EDM wizard infers AssociationSets for any SSDL associations, which, like their CSDL counterparts, act as a wrapper for the Associations. The SSDL AssociationSets will be used for mapping.

2.10.4.1. ReferentialConstraint The ReferentialConstraint element serves a number of purposes. It specifies the direction of the relationship using the Principal and Dependent role elements. In the example, the Address is dependent upon Contact. This also translates to defining the Primary Key / Foreign Key (PK/FK) relationship and we finally see the foreign key in the Addresses table identified: it is the Contact ID. This is another piece of the puzzle of how the Association and the Navigation Property work in the Conceptual model. The ContactID property doesn't exist anywhere in the CSDL, but it is specified here in the SSDL. The MSL will show us how they are linked. The last purpose of the ReferentialConstraint is to stipulate that a row in the Addresses table cannot exist without a reference to a row in the People table. This rule exists in the database but because of the ReferentialConstraint; the Entity Framework will also check this rule. The Entity Framework APIs will check to see if the data passes this rule before it attempts to send the data to the database. If your code creates an address without associating it with a person, the data will fail the constraint check. You will learn more about this later, but it is important to understand that this won't happen at the time when Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 48

Return to Table of Contents

the address is created in code. The check happens when the code attempts to save changes back to the database.

2.10.4.2. More on Referential Constraints There are other rules and constraints in the database which can be described in the Store Schema, such as noting whether the database will perform a Cascading Delete. If you check back at the CSDL's Association in Example 2-2, you will see that this ReferentialConstraint doesn't exist. The CSDL enforces that constraint in a different way. The Multiplicity for the Person Entity Type in that relationship is "1", not "0..1". "1" means "one and only one" where as "0..1" means "zero or one". If application code attempts to add an address that is not attached to a Person, an exception will be thrown. You will learn more about the ins and outs of constraints and validation in Chapter [X].

2.11. MSL – The Mappings

The last section of the model to look at is the Mappings section. In the Entity Data Model, the Mapping layer sits between the Conceptual and Store layer providing not only the map from entity properties back to the tables and columns in the data store, but the mapping layer also enables further customization of the model. You can view mappings in the Designer's Mapping Details window. To follow along, close the XML view of the model and open the model back up in the Designer by double clicking the model's EDMX file in the Solution Explorer. To see the Mapping Details window, right click the Contact entity and select "Table Mapping" from the menu. The window can be docked if you prefer not to have it floating on top of the Designer. The Contact's mapping information will be displayed in the Mapping Details windows. Figure 2-19. Open the Mapping Details window in the designer by right clicking in the background of the model, then choosing "Mapping Details" from the menu that appears.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 49

Return to Table of Contents

Figure 2-19 shows visually how the Contact entity maps to the Contact table in the store layer. This is defined by "Maps to Contact" which refers to the table name in the SSDL. In other words the Contact entity maps to the Contact table. Because the Contact entity has not been customized, the mapping is straight-forward — a one-to-one mapping between the conceptual layer and the store layer. Below the table selection for the Contact table, you can see that the columns from the table (on the left) are mapped to the entity's properties on the right. By default, the designer will match up identical names, which is a great help. You can also see that the columns include the provider type (int, nchar and datetime from SQL Server) whereas the properties include EF's primitive types (Int32, String, DateTime). The "Add a Condition" and "Add a Table or View" can be used for additional customization of the model which will be covered in Chapter [X]. Open the model up in the XML Editor again then expand the section so that you can see that there is one big difference in how the mapping is described under the covers. The mapping is being made between the EntitySet, not the actual entity. When we add inherited types into the mix, you may also be mapping Customers who are a type of Contact. By mapping the EntitySet, it covers all of the entity types in an inheritance hierarchy.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 50

Return to Table of Contents

2.11.1. The MSL Elements Let's back up a bit and take a look at the Mappings section before drilling further into the mapping for the Contact entity. Having inspected the CSDL and SSDL already, the MSL has elements which look familiar, though they are specific to mapping.

2.11.1.1. Mapping Element The first thing to notice is that parent element isn't a Schema, but a Mapping, with its own xml namespace and a Space attribute of "C-S", telling us that it is mapping from C (Conceptual layer) to "S" (Store Layer). You'll find that when discussing the mapping, authors and presenters will use the terms "C-side" and "S-side". They are referring to the Conceptual end of the mapping and the Store end of the mapping.

2.11.1.2. EntityContainerMapping All of the mappings are within the EntityContainerMapping element. This element describes which SSDL and CSDL will be use for the mapping by identifying the same container names which in the SSDL and CSDL listed previously: "dbo" and "ProgrammingEFDB1Entities". Next, the mappings are grouped by EntitySets and Association Sets. Because this is a very simple model, the mappings are easy to read.

2.11.1.3. EntitySet 2.11.1.3.1. EntityTypeMapping The mapping for each EntityType is defined in an EntityTypeMapping element that defines which EntityType is being mapped. Note the syntax used: "IsTypeOf()" with the fully qualified name of the type. IsTypeOf is a .NET framework method. In this particular example, IsTypeOf is not actually required—the model would have the same meaning if the TypeName value was simply "ProgrammingEFDB1Model.Contact". In Chapter [x], examples of entity Inheritance will be explained and there you will see how IsTypeOf can impact the meaning of the mappings.

2.11.1.3.2. MappingFragment The EntityType Mapping element contains a MappingFragment. This doesn't seem logical with our example, but as you will see in Chapter [X] it is possible to do something called Entity Splitting where one entity is comprised of properties that map to columns in multiple tables. In that case, each table that you are mapping to will be represented within Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 51

Return to Table of Contents

a single MappingFragment. The StoreEntitySet refers to the EntitySet for the table listed in the SSDL.

2.11.1.3.3. Scalar Property The ScalarProperty mappings which map the property name of the entity type in the CSDL to the column name of the table. In the case of our simple model, the property names and the field names are identical which makes this particular mapping pretty straightforward.

2.11.2. AssociationSetMapping In the AssociationSetMapping, we can finally see how the associations and Navigation properties work with respect to the "hidden" foreign keys. As the EntitySetMappings are used to map Entities, AssociateSetMappings are used to map an Association. Figure 2-20 displays the MappingAssociation for the CSDL's FK_Contact_People association in the designer. You can open this by right clicking on an association in the designer and selecting "Table Mapping".

NOTE

If the Mapping Details window is already open, it is not necessary to right click objects in order to see their mappings. Just select the object (entity or association) and it's mappings will appear in the already visible window.

Figure 2-20. You can see the Association's mappings in the Designer's Mapping Details window.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 52

Return to Table of Contents

The AssociationSetMapping maps the "FK_Contact_People" Association in the CSDL to the Address table in the SSDL ("Maps to Address"). Remember that the Association is defined as having the Contact Entity on one end of the relationship and the Address Entity on the other end.

NOTE

It might helpful to remember that we made the EntitySet names plural in the CSDL but not the SSDL. The SSDL EntitySet names match the Entity names exactly because both types of names are derived directly from the database table names. The mapping then specifies that the ContactID from the Contact end of the relationship (this refers to the name of the role in the Association), maps to the contactID column in the Address table. So the big mystery is finally revealed! You can finally see that it is the mapping which wires up the navigation from the Contact entity to the Address entity even though there is no ContactID property in the Address entity. While the ContactID enables the mappings to find all of the addresses for one person, we need to also map the AddressID back to the addressID in the table so that we can discern one Address record from another. As you can see in Example 2-4, the behind-the-scenes XML doesn't reveal much more. Example 2-4. AssociationSet Mapping

There's more to be come on Associations and Mappings in Chapter [x], Relationships and Associations.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 53

Return to Table of Contents

2.12. Database Views in the Entity Data Model One type of database object that we haven't explored yet in the EDM is a database view. There is one view in the database that was pulled into the model by the wizard. Views in the database are read-only, so views are surfaced as read only entities in the model. To the EDM, "read-only" means that the Entity Framework doesn't have the ability to automatically build Insert, Update and Delete commands. However, it is possible to use stored procedures to make these entities updatable. In Chatper 4, you'll learn how to map stored procedures to entities. There is nothing in the Property window of the vOfficeAddresses entity to indicate that it is read-only. If you were to dig through the model, you will find that there is something in the SSDL called a DefiningQuery containing the T-SQL from the database which defines the view. Chapter [X], Advanced Modeling and Stored Procedures, will dig further into DefiningQuery. For now, remember that the view comes into the model as an entity and is read-only by default, but can be updated through function mappings. That will carry you far.

2.13. From EDM to Classes: Code Generation Entity Framework automatically creates a set of classes from the model. These classes are what you will work with when you query the model and objects will be returned that are based on these classes. Each time a change is made to the model and the model is then saved, Entity Framework's code generator kicks in and the classes are recreated. You will get many opportunities to learn about and inspect these classes throughout the rest of the book. You will also learn how to customize these classes and learn about customized code generation.

2.14. Summary This chapter has introduced you to the Entity Data Model as well as a bit of the functionality of the Design tools. You have created your first Entity Data Model and looked underneath the covers to gain an expert understanding of the most common pieces of the Entity Data Model. You have done some minor customizations, explored the mappings and even wired up some stored procedures to override the dynamic query generation for database changes. You also learned about handling minor database updates in the model.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 54

Return to Table of Contents

As has been explained previously, the Entity Data Model shines when you can begin taking advantage of the fact that it is highly customizable. Now that you have this solid foundation of the Entity Data Model, you are quite prepared to learn about advanced mappings and customization which will be explored in Chapter [X].

Chapter 3. Foundations of EDM Queries There are a variety of ways to query EDMs. Some you will choose for personal preference and others you will choose to leverage particular benefits. In this chapter, you will finally get to some coding and get at some data by writing queries with the two available query syntaxes—LINQ to Entities and Entity SQL. In addition to the query you will learn about query syntax versus method based syntax including Entity Framework's Query Builder methods. By the end of the chapter, you will have gained a high level understanding of all of the query options and their basic uses. Further chapters will delve into more complex queries and the basis that you will get from this chapter will make this much easier.

Licensed by Dave Olsen

5 Ways to Query the Entity Data Model and 2 Query Languages 1. 2. 3. 4. 5.

LINQ to Entities using LINQ's Query syntax LINQ to Entities using LINQ's Method syntax Object Services use Entity SQL Query syntax Object Services Builder Methods using Entity SQL EntityClient Provider using Entity SQL

At the end of the chapter, there is an extremely important section about Query Execution that deserves calling out. Understanding the possibility of inadvertent query execution in your Entity Framework applications can help you avoid performance problems caused by your application unknowingly and unnecessarily making calls to the database.

3.1. Query the Model not the database The data is still stored away in your database. You will construct queries against the EDM that you created in Chapter 3 and let the Entity Framework take it from there. EF will process your query and leverage the ADO.NET provider, in this case System.Data.SqlClient to turn it into something that the target database will comprehend. After the database has executed the query, the results will then be turned into objects that are based on the entities in the model.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 55

Return to Table of Contents

The resulting objects are an important piece of the querying process but surely, you want to get to the querying, so first we'll query, then take a peek under the covers.

3.2. Your first EDM query In Chapter 3, you created an Entity Data Model inside of a Console Application. Your first queries will be created in that application, so if you've closed it, open it back up and let's get started. The following code will execute a simple query then display the results in a console window. 1. Open the Module1.vb or Program.cs file. 2. Add the following method below the Main method. Intellisense will assist you as you type. After doing a few basic queries, we'll make the code a little more efficient. VB Private Sub QueryContacts() Using context As New ProgrammingEFDB1Entities Dim contacts = context.Contacts For Each contact In contacts Console.WriteLine("{0} {1} {2}", _ contact.Title.Trim, contact.FirstName.Trim, _ contact.LastName.Trim) Next End Using Console.Write("Press Enter...") Console.ReadLine() End Sub C# static private void QueryContacts() { using (var context = new ProgrammingEFDB1Entities()) { var contacts = context.Contacts; foreach (var contact in contacts) { Console.WriteLine("{0} {1} {2}", contact.Title.Trim(),contact.FirstName.Trim(), contact.LastName); } } Console.Write("Press Enter..."); Console.ReadLine(); }

3. Add the following into the Main method. VB QueryContacts C# QueryContacts();

4. Press F5 to run this bit of code. Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 56

Return to Table of Contents

When the code hits the ReadLine(), you'll see that all of the names have been listed in the Console window. You have just executed your first query against the Entity Data Model and seen the resulting objects. 5. Press the Enter key to finish running the app. Now we'll run the query again, but this time look at some of what's going on. 1. Set a break point at the end of the For Each / foreach block. For VB that's the word "Next" and for C# it's the closing brace. 2. Press F5 to run again. 3. When the debugger reaches the breakpoint, hover over the word con and you will see that it is a Contact entity. Figure 3-1. At runtime, the query results contain Contact entities.

4. Next, hover over the word contacts in that same statement to see what it's type is — a System.Data.Objects.ObjectQuery of Contact types. System.Data.Objects is Entity Framework's API for creating and managing Entity Objects. The ObjectQuery is what EF uses to construct and execute queries that will return objects. Once it has been executed, it contains results, which were all of the contacts that you saw listed in the console. Because you only asked for the EntitySet and did not request any filtering, all of the contacts were retrieved from the database when the query was executed. While this doesn't really look like a query, it is —just a very simple one. You'll take a closer look at this after the next query. 5. You can continue the application or stop it by pressing Shift+F5.

3.2.1. A more query-like query Remove the breakpoint that you set in the previous steps. In the line of code that created the contacts memory variable, replace context.Contacts with this query that retrieves a subset of the Contacts. VB Dim contacts=From c In context.Contacts Where c.FirstName = "Robert"

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 57

Return to Table of Contents

C# var contacts = from c in context.Contacts where c.FirstName == "Robert" select c;

NOTE

You'll find many differences between VB and C# syntax when writing LINQ queries. Besides the casing, notice that VB does not require that you explicitly use the Select operator, while C# does. Run the application again and you will see that only a small number of contacts are listed and they all have Robert as their first name. Congratulations, you just wrote a LINQ to Entities query.

3.2.2. Where did the Context and Classes come from? Since you just dove right into the code, you might have a few questions. Where did the Contact type come from? How did we go from an XML file to strongly typed .NET objects? Why is context.Contacts a query and what is that context, anyway? One of the features of the Entity Data Model designer tools is that the designer automatically performs code generation based on the model. If you have your Solution Explorer set to Show All Files, you can see an extra code file attached to the model as shown in Figure 3-2 Figure 3-2. With Solution Explorer's Show All Files active, you can see the code file generated from the model.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 58

Return to Table of Contents

Expand the edmx file in the explorer to see the generated code file. Open the file to see what's in there. Because the file is generated automatically, you don't want to edit it directly. You'll learn how to customize the classes in this file in Chapter [X]. There are four classes in this file. Figure 3-3 shows these classes in the Visual Studio's Class Designer view. The first is ProgrammingEFDB1Entities which has the name of the EntityContainer in the model. The others are for each of the entities — Address, Contact and vOfficeAddresses. Figure 3-3. Figure Caption Text Goes Here

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 59

Return to Table of Contents

3.2.2.1. The ObjectContext class, ProgrammingEFDB1Entities When you looked at the XML view of the model, there was an EntityContainer which contained the EntitySets and AssociationSets. The ProgrammingEFDB1Entities class represents that EntityContainer and inherits from an Entity Framework type called ObjectContext. This is why "context" was used for the variable in the example. ProgrammingEFDB1Entities has three properties – Addresses, Contacts and vOfficeAddresses — which are the EntitySets defined in the model. There is also a method, CustomersbyState, based on the FunctionImport that you created for the READ stored procedure of the same name. The three AddTo methods were created by the code generation to support the entity classes and the ObjectContext itself.

A note for VB developers about Methods vs. Subs & Functions In Visual Basic, we use Subs and Functions which two different types of methods. C# developers call everything a method. For the sake of addressing VB and C# developers concurrently, you will see me use the term "method" generically when discussing what you know as Functions or Subs. Looking more closely at the Contacts property, you can see that it returns an ObjectQuery of Contact types. VB Public ReadOnly Property Contacts() As _ Global.System.Data.Objects.ObjectQuery(Of Contact)

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 60

Return to Table of Contents

C# public global::System.Data.Objects.ObjectQuery Contacts

This is why context.Contacts in the first example was a query even though you didn't write any query specific code.

3.2.2.2. The Entity Classes The three Entities defined in the model were the source for the three entity classes. Each of the classes inherits from EF's EntityObject class and has properties based on the properties defined in the model, including the navigation properties, Contact.Addresses and Address.Contact property. Figure 3-4. Figure Caption Text Goes Here

But there's something new in there, ContactReference, which you'll learn more about later on in the Relationships and Associations chapter. There are more members of these classes but as they are not relevant to the querying that you'll do in this chapter, they will be dissected later on. Dig Deeper: Don't be afraid to poke further around in the generated code file but remember that any changes you make will be overwritten any time that the model is modified and saved. Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 61

Return to Table of Contents

3.3. LINQ to Entities The second query that you wrote was a LINQ to Entities query. LINQ is a new language enhancement that was added to Visual Basic and C# in Visual Studio 2008. LINQ stands for Language INtegrated Query and LINQ to Entities is one of its implementations.

LINQ and its Implementations LINQ was originally written to query in-memory CLR objects, but there are now many implementations of it. You just used an implementation created to work with Entity Objects. Visual Studio 2008 also includes LINQ to SQL, an implementation that queries directly against SQL Server databases. Many third parties are also writing LINQ implementations.

NOTE

It is possible to get very creative with LINQ queries and you will easily find a number of books entirely about LINQ. For starting out it's helpful to understand the basic structure. The most obvious exhibit of the integration is that as you typed your query, you had the benefit of Intellisense assisting you, for example, providing LastName as an option for the con variable. That was because when you identified the Contacts EntitySet at the beginning of the query, the compiler was able to determine that the items in that collection are Contact items. When you typed "con" later in the query in the SELECT and WHERE clauses, Intellisense was able to present a list of Contact properties in the Intellisense suggestions.

Why Does LINQ start with FROM? LINQ queries begin with the FROM clause rather than SELECT which most of us are familiar with in other query languages. When LINQ was first being created, it did begin the query statement with SELECT. However, the developers at Microsoft quickly realized that by first identifying the type that is being used, Intellisense is able to provide meaningful suggestions as the rest of the query is constructed.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 62

Return to Table of Contents

According to Microsoft's Y. Alan Griver, who was very involved with the LINQ project during its early stages, the developers at Microsoft jokingly referred to this syntax as "Yoda speak" when they altered the syntax for the sake of Intellisense. In the query, "con" is just a random variable name so that you can reference the thing which you are working with further on in the query. It's referred to as a "control variable". The control variable provides another means by which Intellisense and the compiler are able to make LINQ more powerful for developers.

3.3.1. ObjectQuery and LINQ to Entities You've seen that ProgrammingEFDB1.Contacts returns an ObjectQuery of Contact types. This is evidenced in the generated code as well as at runtime. There is a small twist on this that you may have noticed. At design time, when you hover over the contacts variable returned by the LINQ to Entities query, the tooltip doesn't say that contacts is an ObjectQuery. Instead it says that contacts is an IQueryable. IQueryable is a LINQ querytype. At design time, the compiler recognizes the LINQ query and does its best to tell you it's return type. The compiler doesn't realize that because it is a LINQ to Entities query, it will be processed by Entity Framework and will result in an ObjectQuery. ObjectQuery implements IQueryable so they are very closely related. IQueryable contains metadata about the query such as the query expression and the Provider being used. ObjectQuery is an IQueryable with additional query details that are specific to Entity Framework queries. At runtime, you'll see evidence of this again if you open up the query variable, contacts, in the QuickWatch window. Figure 3-5. ObjectQuery implements LINQ's IQueryable. Don't let this confuse you when LINQ to Entities display its type as IQueryable in some places and ObjectQuery in others.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 63

Return to Table of Contents

Once an IQueryable (and an ObjectQuery because it implements IQueryable) has been executed, it contains it's query metadata as well as the new query results. The results are described as an "enumerable type", based on the class, IEnumerable, which is similar to a Collection. An IEnumerable allows you to enumerate or iterate through each item in the collection as you did in the above code sample (For Each/foreach). A Collection is an enhanced IEnumerable. While an IEnumerable is read-only, the more familiar Collection class allows you to perform additional actions such as adding or removing items from the group.

Terminology: Collection vs. IQueryable and IEnumerable It is important to be familiar with the terms IQueryable and IEnumerable because they are used frequently when discussing LINQ (not just LINQ to Entities) and Entity Frameowork queries. While saying "this query returns a Collection" is more easily understood by developers, "this query returns an IQueryable/IEnumerable" is more technically correct.

3.4. Creating ObjectQueries Directly In the second example, an ObjectQuery was implicitly created by the LINQ to Entities query, while you conveniently used the LINQ syntax built directly into Visual Basic and C#. There is one other way to create ObjectQueries and that is by using Entity Framework's Object Services (in the System.Data.Objects namespace) directly. When creating ObjectQueries directly, you will use Entity Framework's T-SQL like query language called Entity SQL to build the query expression. Modify your example with the following steps. 1. Replace (or comment out) the line of code containing the LINQ to Entities query with the following two lines. VB Dim qStr = "SELECT VALUE c " & _ "FROM ProgrammingEFDB1Entities.Contacts AS c " & _ "WHERE c.FirstName='Robert'" Dim contacts = context.CreateQuery(Of Contact)(qStr) C# var queryStr = "SELECT VALUE c " + "FROM ProgrammingEFDB1Entities.Contacts AS c " + "WHERE c.FirstName='Robert'"; var contacts = context.CreateQuery(queryStr);

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 64

Return to Table of Contents

2. Hover your mouse over the word "contacts" and you will see that at design time it is an ObjectQuery (Of Contacts). 3. Run the app again and the results will be the same as before.

3.4.1. Why another way to query? Why would you need another means of querying the EDM in addition to LINQ to Entities? The main reason lies in the use of the string-based query which you passed into the CreateQuery method. If you have constructed SQL queries before, this syntax looks familiar but not quite right. This is the a specialized query language for the Entity Framework and is called Entity SQL. The return type of this query at design time is an ObjectQuery(Of Contact), not IQueryable. This means that at design time, you have access to ObjectQuery's properties and methods in code which will give you much more granular control over the query execution and some other features. You will learn more about controlling ObjectQueries at a later time in this book.

3.4.2. Entity SQL Entity SQL was actually the first syntax devised for querying Entities. LINQ was being developed as a language extension elsewhere at Microsoft and eventually, it was obvious that LINQ would be a fabulous addition to the Entity Framework, which is how LINQ to Entities came to be. Entity SQL has its roots in SQL because it makes sense to start with something that is wellknown. However, because entities are different than a relational data, EntitySQL deviates from SQL in order to provide the necessary capabilities for querying the Entity Data Model.

How is EntitySQL Different from T-SQL? The Entity Framework documentation has a topic called "How Entity SQL Differes from Transact-SQL". It provides a list of differences with an extended explanation for each difference. For example, Entity SQL supports the Inheritence and Relationships found in an EDM where in TSQL you must use joins to work with relationships. Databases do not even have the concept of inheritance, therefore TSQL doesn't support that either. Looking more closely at the Entity SQL query string built above, you'll notice that, like LINQ to Entities, it defines a variable for use in the query, "con". In LINQ this is referred to as a control variable, but in Entity SQL it is just called a variable. Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 65

Return to Table of Contents

Figure 3-6 deconstructs the query string without the WHERE clause. The variable is defined using the AS keyword and is referenced in the SELECT clause. The VALUE keyword specifies that you want to return a collection of single items; in this case it will be Contact entities. Figure 3-6. Deconstructing a simple Entity SQL query

The VALUE clause is required if you are selecting a single item which can be an entity, a single property or even entity collection. SELECT VALUE c FROM ProgrammingEFDB1Entities.Contacts ... SELECT VALUE c.FirstName FROM ProgrammingEFDB1Entities.Contacts ... SELECT VALUE c.Addresses FROM ProgrammingEFDB1Entities.Contacts ...

If you are selecting multiple items, then you cannot use VALUE. SELECT c, c.Addresses FROM ProgrammingEFDB1Entities.Contacts .... SELECT c.LastName,c.Title FROM ProgrammingEFDB1Entities.Contacts ...

If you forget VALUE, an InvalidOperationExcpetion will be thrown at runtime telling you that .NET is unable to cast a System.Data.Object.MaterializedDataRecord to the type that you specified in the ObjectQuery. If you include VALUE with multiple items, an EntitySqlException will be thrown that specifically tells you "SELECT VALUE can have only one expression in the projection list."

It will even tell you the line number and column number of the problem.

NOTE

Chapter [X] delves more deeply into Entity Framework exceptions.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 66

Return to Table of Contents

Without the VALUE clause, the results will be wrapped in rows and you will have to dig into the rows and columns to get at the data. Similar to the LINQ query, you are selecting FROM a collection. In this query, that collection is the entity set, Contacts; but it is necessary in Entity SQL to specify the EntityContainer as well. Again, "con" is a random variable name used for the query used to represent contact items within the Contacts entity set. The WHERE clause in the Entity SQL uses SQL-like syntax. WHERE c.FirstName='Robert'

3.4.3. Entity SQL supports over 100 operators and functions While it would be impossible to cover all of operators and functions supported by Entity SQL, the language is very robust and offers a lot of functionality. You will see many of them used throughout the book and you can get the full list by looking at the Entity SQL documentation in the MSDN Library. There is a large set of Canonical functions, meaning functions that should be supported by all data providers. Entity SQL also supports the ability of each data provider to include their own specific functions. The .NET Framework Provider for SQL Server, written by Microsoft, offers approximately 75 specific functions that can be used in Entity SQL queries when the target database is SQL Server. Some of these do overlap with the canonical functions. The provider additionally provides the primitive types and their facets and the internal logic for mapping between the EDM and SQL Server. Other providers that are written for the EDM will have their own lists of additional functions and features that are supported.

NOTE

If you are familiar with T-SQL, you'll be happy to know that one of the canonical functions is Trim(), which means that you won't have to use the silly LTRIM(RTRIM()) combo any more.

3.4.4. Entity SQL is Case Sensitive 3.4.5. Parameterized ObjectQueries ObjectQuery allows you to create parameterized queries. They work similarly to other query languages by using an @ placeholder in the string, then defining its value in a parameter.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 67

Return to Table of Contents

In order to use a parameterized query, you need to explicitly instantiate an ObjectQuery, rather than use the CreateQuery method of the ObjectContext. Using this method, you also need to pass the ObjectContext as a parameter when you instantiate an ObjectQuery. Then add parameters to the ObjectQuery prior to execution. The same query you have been writing could be rewritten to enable dynamic changes to the query like this: queryString = _ "SELECT VALUE c FROM ProgrammingEFDB1Entities.Contacts AS c " & _ "WHERE LEFT(c.lastname,1)=@lastnameLetter" Dim contacts As New ObjectQuery(Of Contact)(queryString, context) contacts.Parameters.Add (New ObjectParameter("lastnameLetter", "S"))

While it may seem tempting, you cannot use parameters to replace property names in the query string. In other words if you tried to create the Entity SQL string "SELECT @myproperty FROM ProgrammingEFDB1Entities.Contacts AS c" and created a parameter that set @myproperty to "c.LastName", the resulting SQL would look like this: ""SELECT 'c.LastName' FROM ProgrammingEFDB1.Entities.Contacts AS c" which is invalid and will throw an error. ObjectParameters do not allow you to specify the length of the parameter. This, like the other ways of querying Entity Framework causes a inefficiencies with your database's query plan caching. This problem and a workaround that you can achieve with ObjectQueries will be discussed in Chapter [X], Chapter 15

3.5. Method Based Syntax Queries for LINQ and Entity SQL So far, the queries you have looked at with LINQ to Entities and Object Services have been written as standard query expressions. Both LINQ to Entities and Object Services provide a way to write queries as method rather than, in the case of LINQ, operators and functions and in the case of Entity SQL, a string. Each query language has a method syntax that you can use, but they exist for opposite reasons. The C# and Visual Basic implementations of LINQ sit on top of query methods in .NET 3.5. Your LINQ expressions are translated into these query methods, but you can use them directly if you like. Entity SQL is processed directly by Entity Framework; however, there is a method based syntax that will construct Entity SQL expressions for you. Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 68

Return to Table of Contents

3.5.1. LINQ Method Based Queries While Visual Basic and C# understand LINQ syntax, the CLR does not. One of the first things to happen when .NET processes LINQ queries is that it translates the query into a set of method calls on the collection being queried.). All of the standard query operators (WHERE, SELECT, JOIN, etc.) have associated methods in .NET 3.5. You can write your queries using the method syntax directly, if you prefer - and many developers do happen to prefer this, while many others would rather use the expression syntax. The MSDN documentation says "In general, we recommend query syntax because it is usually simpler and more readable; however there is no semantic difference between method syntax and query syntax." Therefore, using one over the other becomes a matter of style and personal choice. In order to write method based queries, you will need to leverage a new feature introduced in .NET 3.5 called lambdas. Lambdas are in-line methods that can be passed into a method which evaluates the method. If you have are new to LINQ and lambdas and have never used anonymous delegates before (which don't' exist in Visual Basic), this will make more sense after seeing some examples. For example instead of this standard Where clause, "Where LastName='Hesse'", the Where() method requires the condition, "LastName='Hesse'" as a parameter. These are written very differently in C# and Visual Basic.

Wrapping your head around Lambdas There's no question that lambda expressions are a little confusing at first; but once you get the hang of them, they make perfect sense and can help you write some very efficient code. Admittedly, my own Visual Basic background prepared me a little less for lambdas then had I been programming in C++ or more frequently in C#. There are some great articles that can help you learn more about lambda expressions. For C#, this excellent MSDN Magainze article by Anders Hejlsberg (aka "The father of C#") called "The Evolution Of LINQ And Its Impact On The Design Of C#" [http://msdn.microsoft.com/msdnmag/ issues/07/06/CSharp30] has a great explanation of lambdas. For Visual Basic, another great MSDN Mag article, this time by Timothy Ng of the VB team, called "Basic Instincts: Lambda Expressions" [http://msdn.microsoft.com/ msdnmag/issues/07/09/BasicInstincts] puts lambdas in perspective for Visual Basic developers.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 69

Return to Table of Contents

Here is the query we have been using in the previous examples now written in method based queries. In Visual Basic, the expression begins with Function, to indicate that you are performing a function on a variable control; then it states the condition. The control variable, "con" in this example, is named on the fly. Dim contacts = context.Contacts _ .Where(Function(c) c.FirstName='Robert')

A C# LINQ to Entities query using the method based syntax looks very different. var contacts = context.Contacts .Where(c => c.FirstName=='Robert');

C# lambda expressions begin by identifying the control variable followed by the => ("lambda") then the expression, [controlVariable].FirstName=='Robert'. In the Where clauses, the expression which returns a Boolean is called a predicate. The query will return all of the contacts for which the expression evaluates to True. Try it out. 1. Replace your existing query with one of the method queries. You will see that Intellisense is still pretty helpful, even when writing the lambdas. 2. Press F5 to run the application. The results will be the same as before.

3.5.1.1. Chaining Methods You can combine LINQ query methods to build more useful expressions. This is referred to as "chaining". An OrderBy method is added to the previous query. Notice that the lambda expression for OrderBy does not need to evaluate a condition to see if it is true or false as does the Where method. It only needs to return a property. VB Dim contacts = context.Contacts _ .Where(Function(c) c.FirstName='Robert') _ .OrderBy(Function(foo) foo.LastName) C# var contacts = context.Contacts .Where((c) => c.FirstName == "Robert") .OrderBy((foo) => foo.LastName);

NOTE

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 70

Return to Table of Contents

When a method's signature requests a predicate, remember that this refers to an expression that returns a Boolean, otherwise the lambda only needs to be a function as in the OrderBy method. You'll see that in Visual Basic, the signatures of all methods refer to this as a Function. The C# methods specifically refer to Predicate in the methods which require an expression that returns a Boolean. You can view the signatures of the various LINQ to Entities method in the MSDN Documentation topic "Supported and Unsupported Methods (LINQ to Entities)". While you can easily use the same variable name throughout compounded methods, the variables don't represent the same instance. In the above LINQ query, the variables were named differently to highlight how the compiler evaluates the query. LINQ actually evaluates the query one method at a time. First it evaluates context.Contacts. Then it applies the Where method to those results. Finally it applies the OrderBy method to the results of the Where method. The "c" in the Where method refers to the items returned by context.Contacts. The "foo" in the second refers to the IQueryable that is returned by context.Contacts.Where(....). Evaluating one method at a time does not mean processing one method at a time. LINQ to Entities will evaluate this query one method at a time and then create a store command based on the complete method, unless you are also using methods that must be performed on the client side. It does not execute each method separately. Here is the resulting TSQL from the above query. SELECT [Extent1].[ContactID] AS [ContactID], [Extent1].[FirstName] AS [FirstName], [Extent1].[LastName] AS [LastName], [Extent1].[Title] AS [Title], [Extent1].[AddDate] AS [AddDate], [Extent1].[ModifiedDate] AS [ModifiedDate] FROM [dbo].[Contact] AS [Extent1] WHERE N'Robert' = [Extent1].[FirstName] ORDER BY [Extent1].[LastName] ASC

3.5.2. ObjectQuery's Query Builder Methods It's possible to use Entity SQL with method syntax as well, although there are a limited number of methods available, thirteen in fact, including Where and Select. These methods are called Query Builder Methods. Query Builder Methods will do as their name suggests. When using these methods, they will build the correct Entity SQL strings for you. While the Query Builder methods may look like some of the LINQ methods, they are definitely different. The compiler can tell when you are using a Query Builder method

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 71

Return to Table of Contents

based on the parameter expression which will either contain a lambda expression for LINQ queries or an Entity SQL expression.

NOTE

Since you have only explored WHERE and SELECT so far while learning about the different ways to query, we'll hold off on listing methods and operators until a bit later. Here is the latest query using Entity SQL as the method parameters. VB Dim contacts = context.Contacts _ .Where("it.FirstName = 'Robert'") _ .OrderBy("it.LastName") C# var contacts = context.Contacts .Where("it.FirstName = 'Robert'") .OrderBy("it.LastName");

The most common question about these expressions is "where did 'it' come from?" "It" is the default alias for the control variable. This way you don't need to define the control variable as you have had to do with all of the other queries we have looked at so far, though it is possible to define your own, as you'll see in the next example. When debugging, you can inspect the CommandText property of the contacts ObjectQuery to see that the builder did indeed build the Entity SQL for you. It's a little more complex than what you might have written yourself. This is a result of the query builder's need to be flexible. Additionally, it does not specify the EntityContainer name in the expression, something that you can't get away with when building the Entity SQL yourself. SELECT VALUE it FROM (SELECT VALUE it FROM ([Contacts]) AS it WHERE it.FirstName = 'Robert') AS it ORDER BY it.LastName

Even when used as a method parameter, Entity SQL provides the same benefits over LINQ to Entities as it does when being used in a query expression. If you need to dynamically build the strings for the expressions or if you need to leverage provider specific functions, once again, Entity SQL is the way to go. Another interesting difference is that using query builders with Entity SQL expressions removes any syntax differences between Visual Basic and C#.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 72

Return to Table of Contents

Whether you use LINQ predicates or Entity SQL predicates, at compile time, the Entity Framework will be able to determine which query compilation path to choose by looking at the predicate.

3.5.2.1. Specifying the control variable As you can see, the Query Builder methods also can be combined. Notice that even in this case, the control variable is always "it" by default. You could actually break the query up and explicitly change the names of any control variables. But you can't change the first. Dim contacts = context.Contacts _ .Where("it.FirstName = 'Robert'") contacts.Name = "cons" Dim orderedContacts = contacts.OrderBy("cons.lastname") C# var contacts = context.Contacts.Where("it.FirstName = 'Robert'"); contacts.Name = "cons"; var orderedContacts = contacts.OrderBy("cons.lastname");

The example demonstrated an additional feature called Composable queries. A query was defined (contacts) and then another query was written using that query. The first query does not get executed separately. It becomes part of the second query.

3.6. The Shortest Entity SQL Query Remember the first query in this chapter? Dim contacts = context.Contacts

In this case, context.Contacts refers to the Contacts property of the Entity Container. If you look back at the generated code from the model you can see that context.Contacts returns this query: VB MyBase.CreateQuery(Of Contact)("[Contacts]") C# this._Contacts = base.CreateQuery("[Contacts]");

This is an ObjectQuery of Contact types but it doesn't use an Entity SQL expression. This is a shortcut that works only when you are not applying any functions to the query, no filters, sorting or any of the possible query functions. By passing in just the name of the EntitySet, Entity Framework will do the rest of the work. You can use this shortcut yourself as well.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Return to Table of Contents

Page 73

3.7. Combing LINQ Methods and Query Builder Methods Because the methods are evaluated incrementally, it is possible to combine the LINQ query methods and the QueryBuilder methods. Then you can get the variety of methods, strong typing and Intellisense provided by LINQ, plus the ability to build dynamic expressions, use provider functions and other benefits of Entity SQL.

3.8. EntityClient – the lowest level method for returning streamed data through EDM queries There is still one additional way to query the Entity Data Model — Entity Client. Entity Client differs from LINQ to Entities and Object Services because it does not materialize objects. Instead, it streams data back to the requesting application as rows and columns in an EntityDataReader, which implements DbDataReader. If you have previous experience with ADO.NET, EntityClient is comparable to SqlClient, OracleClient and other client providers and these clients return SqlDataReader, OracleDataReader, etc. which also implement the DbDataReader. A data reader represents data in rows and columns. With the familiar DataReaders, each "cell" contains a scalar value – in other words a primitive type such as a string or an integer. For example:

Row1 Row2 Row3

Col1 1 2 3

Col2 John Jessica Cecil

Col3 Doe Rabbit DeMille

Each row in the DataReader can be represented as a dbDataRecord object. EntityDataReaders are designed to represent the relationships that exist in an Entity Data Model, therefore scalar data is not enough. An EntityDataReader has the ability to return data as shaped results. Therefore the cells above could not only contain scalar values, but an entire DbDataReader, a DbDataRecord (a single row from a DbDataReader) or even EntityKey object. You have seen EntityKey as a property of an EDM; the EntityKey class is a full class implementation based on that property which you will learn more about in Chapter [X]. EntityClient uses Entity SQL for its query syntax and is comprised of methods and properties that you have used if you have worked with ADO.NET previously, Connections, Commands, Parameters and Transactions.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 74

Return to Table of Contents

This next example will give you a chance to work with EntityClient yourself and is followed by an explanation of the code. 1. Add the following namespace declarations to the beginning of the code file to pro VB Imports System.Data.EntityClient C# using System.Data.EntityClient;

2. Add the following method to your existing code (Module.vb or Program.cs) to perform the same query which you wrote with LINQ to Entities and Object Services above using the EntityClient provider. VB Private Sub EntityClientQueryContacts() Using conn As EntityConnection = _ New EntityConnection("name=ProgrammingEFDB1Entities") conn.Open() Dim queryString = _ "SELECT VALUE c " & _ "FROM ProgrammingEFDB1Entities.Contacts AS c " & _ "WHERE c.FirstName='Robert'" Dim cmd As EntityCommand = conn.CreateCommand() cmd.CommandText = queryString Using rdr As EntityDataReader = _ cmd.ExecuteReader(CommandBehavior.SequentialAccess) Do While rdr.Read Dim firstname = rdr.GetString(1) Dim lastname = rdr.GetString(2) Dim title = rdr.GetString(3) Console.WriteLine("{0} {1} {2}", _ title.Trim, firstname.Trim, lastname) Loop End Using conn.Close() Console.Write("Press Enter...") Console.ReadLine() End Using End Sub C# static void EntityClientQueryContacts() { using (EntityConnection conn = new EntityConnection("name=ProgrammingEFDB1Entities")) { conn.Open(); var queryString = "SELECT VALUE c " + "FROM ProgrammingEFDB1Entities.Contacts AS c " + "WHERE c.FirstName='Robert'"; EntityCommand cmd = conn.CreateCommand(); cmd.CommandText = queryString;

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 75

Return to Table of Contents

using (EntityDataReader rdr = cmd.ExecuteReader(System.Data.CommandBehavior.SequentialAccess)) { while (rdr.Read()) { var firstname = rdr.GetString(1); var lastname = rdr.GetString(2); var title = rdr.GetString(3); Console.WriteLine("{0} {1} {2}", title.Trim(), firstname.Trim(), lastname); } } conn.Close(); Console.Write("Press Enter..."); Console.ReadLine(); } }

3. Call this new method from the Main method

NOTE

You may want to comment out the call to QueryContacts so that only the new method is run 4. Press F5 to test the new method. The results will be the same as the previous to queries. There is a bit to explain about the code for calling the EntityCommand.

3.8.1. EntityConnection and the Connection String With other client providers, the connection connects directly to the data store. The EntityConnection, however, provides a connection to the EDM. When you created the model with the Wizard, you may remember seeing the odd connection string in the wizard page where you selected the connection. An Entity Connection String consists of pointers to the compiled EDM schema files as well as a database connection string. The EntityConnection string was written into the app.config by the wizard. You can open this file up from Solution Explorer and see that the ConnectionString named ProgrammingEFDB1Entities is made up of three parts: metadata, provider and provider connection string. The metadata contains file path pointers to the three schema files that are created from the model when the project is built. The data provider refers to the SqlClient provider that is being used to connect to the SQL Server database in this example and finally the provider connection string is a standard database connection string.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 76

Return to Table of Contents

metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl; provider=System.Data.SqlClient; provider connection string= "Data Source=MyServer; Initial Catalog=ProgrammingEFDB1; Integrated Security=True; MultipleActiveResultSets=True"

NOTE

The * in the metadata indicates that the files are embedded into the assembly file of the project that contains the model and its classes. This is the default although you can specify that the files be saved to the file system. You'll learn more about this in Chapter [X], Making it Real. EntitConnection provides for an easy way to reference the connection string in the config file which is by setting a name property to the same name of the connection string – "name=ProgrammingEFDB1Entities".

3.8.2. EntityCommand Creating the EntityCommand is no different than creating any other provider command and setting its CommandText. The CommandText here is the Entity SQL expression defined in the variable, queryString.

3.8.3. ExecuteReader With EntityClient, the SequentialAccess CommandBehavior is required for the ExecuteReader method. With other DbDataReaders, rows must be accessed sequentially, but the columns within the rows need not be. This rule exists to control memory consumption.

3.8.4. Forward Only Access to the fields DbDataReaders are streams of data and are by definition, forward-only. This also means that the columns must be read this way which makes the next bit of code a little cumbersome. In the string concatenation we want to combine the fields to read Title FirstName LastName. But this is not the order of the fields returned in the DataReader. Title is the 4th column in the row, while FirstName is second and LastName is third, therefore you cannot read the Title data first but must read the fields in the order that they are streaming in.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 77

Return to Table of Contents

That is why this method creates the variables prior to building the string — so that the data can be extracted in sequential order. Once the variables exist, you can build the string. This is an important lesson to remember, regardless of how you plan to use the streamed data returned by the EntityClient.

3.9. Translation to Database queries While the query processing will be explored in detail in later part of this book, you may already be wondering what kind of query is Entity Framework sending to your database. Entity Framework will break down the LINQ or Entity SQL query into a command tree and with the help of the EDM and the database provider, create another command tree that is specific to the database. You can imagine how flexible the API needs to be to pull this off no matter what query you write. Although the examples so far have been simplistic, it is possible to write very complex LINQ to Entities or Entity SQL queries. Entity Framework needs to be able to deal with anything that is thrown at it. Therefore queries may not look exactly the same as you might write them directly in your database's query syntax because they are being constructed in a somewhat formulaic manner. Sometimes, the queries may look more complex, but may have no negative impact whatsoever on performance. But don't expect this to always be the case. There are a few ways to see the actual TSQL built from your query. ObjectQuery has a ToTraceString method that will let you see the store command. You would have to add this to your code to see it however. We'll do this in a later chapter. A simpler way for now (for those working with SQL Server Professional and above), is to use the SQL Profiler tool in SQL Server. Here is the TSQL rendered from the LINQ to Entities and Entity SQL queries which returned Contacts named Robert. SELECT [Extent1].[ContactID] AS [ContactID], [Extent1].[FirstName] AS [FirstName], [Extent1].[LastName] AS [LastName], [Extent1].[Title] AS [Title], [Extent1].[AddDate] AS [AddDate], [Extent1].[ModifiedDate] AS [ModifiedDate] FROM [dbo].[Contact] AS [Extent1] WHERE [Extent1].[FirstName] = 'Robert'

The queries result in the same T-SQL because they are fairly simple queries.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 78

Return to Table of Contents

3.9.1. Pay attention to .NET Method's impact on generated SQL As you write queries, it's a good idea to keep an eye on the generated SQL since it possible to write queries in different ways where you would get the same results, but perhaps not generate the same store command. A good example of this is combining .NET methods with LINQ. .NET String has a handy method named StartsWith which evaluates the first character in a string. VB From c In context.Contacts _ Where c.LastName.StartsWith("S") C# from c in PEF.Contacts where c.LastName.StartsWith("S") select c

Even though TSQL has a handy LEFT function, because of the way StartsWith is evaluated by .NET, it is not interpreted as LEFT. Instead you get the following WHERE clause in SQL Server. WHERE (CAST(CHARINDEX(N'S', [Extent1].[LastName]) AS int)) = 1

The use of CAST has a performance impact in SQL. Visual Basic actually has a LEFT method which you can use in LINQ. From c In PEF.Contacts _ Where Left(c.LastName, 1) = "S"

This query does cause the TSQL LEFT function to be used. WHERE N'S' = (LEFT([Extent1].[LastName], 1))

Unfortunately, C# does not have a comparable function. The best choice for C# would be to use SubString. from c in PEF.Contacts where c.LastName.Substring(0, 1) == "S" select c

This reults in the following WHERE clause: WHERE N'S' = (SUBSTRING([Extent1].[LastName], 0 + 1, 1))

What about SQL Injection Attacks? LINQ and Entity SQL protect your database from SQL Injection Attacks. SQL Injection attacks can be used to insert commands into your queries that can Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 79

Return to Table of Contents

display data or impact your database by leveraging your connection to the database and any permission your connection may have. This is a common threat to database applications and you can find plenty of information in books and on the web about how to avoid them. LINQ to Entities queries are always resolved as parameterized queries thus avoiding SQL Injection. In Entity SQL, most SQL injections wont' even evaluate as correct Entity SQL Syntax and therefore cannot be executed. However someone could attempt to inject Entity SQL. Chapter 13, Making it Real, addresses Security in Entity Framework where you can read more about this topic.

3.10. Avoid Inadvertent Query Execution You may have noticed when debugging some of the queries above, that next to the Results property it says "Expanding will process the collection." This is a very important concept to be aware of and it impacts all LINQ queries (including in-memory vqueries and LINQ to SQL) as well as ObjectQuery queries. Whether you do it in debug mode or in code, every time you do anything to force the enumeration of a query, the query will be processed again. What this means in Entity Framework is that even if you have already done something to enumerate the query (e.g. bound it to a control, run through a foreach iteration, called ToList() on the query), any time you repeat one of these methods that force execution, it will go back to the database, run the query again, bring back the results again and then merge the results into the cache that's in memory. ToList is a convenient way to force query execution and provide a variable to work with. That variable will be a System.Collections.Generic.List(Of T) (List in C#) of whatever type the query returns. Another method that you can use is ObjectQuery.Execute which will also force execution. Execute returns a System.Data.Objects.ObjectResult(Of T) ( in C#). ObjectResult has some special functionality that makes it the right choice for databinding scenarios. You'll see ObjectResult in used in later chapters where you will be doing databinding in various applications. Execute takes a MergeOption parameter that specifies how the query results should be merged into existing entities. You'll learn more about MergeOption in Chapter 8 on Object Services. You will see ToList and other methods used throughout this book to avoid accidentally repeating query execution. Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 80

Return to Table of Contents

3.11. Chapter Summary In this chapter, you learned about the many different ways to query an Entity Data Model, LINQ to Entities, ObjectQueries with Entity SQL, LINQ Methods and Query Builder Methods and streaming data with EntityClient. Along the way, you also learned about many of the fundamentals that will make it easier for you to construct intelligent queries. Chapter 7, Object Services, will spend time comparing how these queries are processed so that you can see the different paths that the different methods of queries embark on was they are resolved. Chapter 13 will cover the performance differences between the various query methods and demonstrate ways to impact performance directly.

Licensed by Dave Olsen

While this chapter focused on a single simple query with a twist here and there, the next chapter will delve more deeply into querying, demonstrating ways to retrieve more complex data using all of the methods that you are now familiar with.

Chapter 4. More Querying the EDM In Chapter 3 , you wrote the same basic query over and over and over again. Hopefully you'll agree that this was a great way to get exposure to the many different ways of writing queries against the Entity Framework. There is a lot more to querying the EDM. You'll need to learn about the flexibility you have for expressing complex queries, projecting data, composing and nesting queries, and writing parameterized queries. There are also nuances about what type of data is returned based on how you construct your queries. Sometimes you will get objects as we've seen in the above example, but other times you will get unknown objects (anonymous types). It is also possible for Object Services queries to return rows and columns. You'll need to know when to expect these varied forms of data to be returned. To cover all of this exhaustively would take thousands of pages. Therefore, the goal of this chapter is to expose you to the critical features and some of the possibilities. You will learn how to project specific values (rather than entire objects) in queries, how to query across relationships, how to write nested queries and joins and how to control when trips are made to the database. Along the way, more new concepts will be introduced and explained to ensure that you can truly understand the workings of the Entity Framework. Throughout the rest of the book, you will see variations on queries taking advantage of even more interesting techniques.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 81

Return to Table of Contents

There are a number of resources that provide many specific examples of queries. Here you will learn the foundations, so that you will know enough to write queries without constantly having to go searching for that perfect example of what you are trying to accomplish so that you can copy and paste it. Don't expect that you will never have to rely on that "query by example" technique either though! We all do at one time or another. It is also useful to check out resources such as the 101 LINQ Examples on MSDN (for VB and for C#) and the Entity Framework Samples which provide a great variety of query examples with helpful commentary.

4.1. Same Model, Friendlier Name The examples in this chapter will continue to use the same model that you have worked with in the previous chapters. As you may have noticed in Chapter 3, writing the Entity SQL queries with the model's long Entity Container name, ProgrammingEFDB1Entities, was a bit cumbersome. This was the default name given by the wizard which based the name on the database name. Since you will be writing more Entity SQL expressions in this chapter, you may want to modify the EntityContainer name so that you have something simpler to type. The designer makes this easy to do. Open the model in the designer then click on the background of the model. This will cause the model's properties to show up in the Properties window. Change the EntityContainerName to PEF. This change will have an impact in three places in your application. 1. PEF will be the new EntityContainer name for the model. 2. PEF will be the new name of the EntityContainer class that you will instantiate to perform queries. 3. The name of the connection string in the app.config file will change to PEF. You should double check that the change was made in all three locations.

NOTE

You will also need to change any existing code references that use this model from the longer name to the new short name. If you are using Find & Replace, you will be better off replacing instances in "Current Document". This new name is not a recommended naming convention, but a convenience for the sake of writing numerous Entity SQL queries in this chapter. Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 82

Return to Table of Contents

Some New Lingo Here is a list of terms used in this chapter (and throughout the book) that may be new to you. Projection Selecting specific properties or expressions in a query rather than the entity being queried. Example: from c in context.contacts select c.firstname + c.lastname, c.contactID Deferred Loading Returning to the database to grab data related to what has already been returned by a query. Example: Query contacts. When working with the query results, load the Addresses from the database for a particular contact. When deferred loading happens automatically (implicitly), it is called as "Lazy Loading". Eager Loading At the time of the query execution, include data related to the data which is being queried. Example: When querying contacts, eager load their Addresses. The contacts and addresses will be retrieved in a single query. Navigating Moving from an entity to its related data. Example: Navigate from a contact to its Addresses using the contact.Addresses property.

4.2. Projections in Queries So far, the queries you have seen above return an entire object, comparable to writing "SELECT *" in a SQL query. By returning an entire object in your query, you will get all of the benefits associated with the entity classes, most importantly the ability to keep track of changes to an entity class for database updates. However you may be getting much more data than you want to work with. Not only might this be a drag when you are programming, but it also means that you are forcing the database to do more work than necessary, causing more data to be transferred than Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 83

Return to Table of Contents

necessary and asking Object Services to materialize objects when that may not be necessary. If you are concerned about the performance of your applications, all of this extra effort will make your application processing inefficient. Often in SQL, you will select particular columns to return from a table (SELECT Firstname, Lastname FROM Contact) or from a set of joined tables. This is referred to as projection. With LINQ or Entity SQL queries you can shape your results by picking particular properties or expressions rather than entities. You can also select properties from related data. In the previous queries, you returned an entire object but only used the Title, Firstname and Lastname properties. You can rewrite those queries to return only these three properties.

4.2.1. Projections in LINQ to Entities In the QueryContacts method, modify the query replacing Select con with the projected properties: Example 4-1. Simple LINQ to Entities Query VB Dim contacts = From c In context.Contacts _ Where c.FirstName= "Robert" _ Select New With {c.Title, c.LastName, c.FirstName} C# var contacts = from c in context.Contacts where c.LastName.StartsWith("S") select new { c.Title, c.FirstName, c.LastName };

4.2.1.1. VB and C# Syntax Differences You may have noticed the syntax difference between VB and C# projections. This is not particular to LINQ to Entities, but common for all implementations of LINQ. C# requires that you use select new {...} when projecting. Visual Basic is more lenient. The most explicit syntax for VB is Select New With {...} as in the above code sample, though you could write the query in this simpler format. From c In context.Contacts _ Where c.FirstName= "Robert" _ Select c.Title, c.LastName, c.FirstName

NOTE

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 84

Return to Table of Contents

There are plenty of other nuances to LINQ projections in both languages. You can project into predefined types. C# projections always create immutable (read-only) results while VB allows the creation of immutable and mutable results. You can learn more about projecting with LINQ in the MSDN Library and the many great resources that focus on LINQ.

4.2.2. LINQ Projections and New Language Features If you hover your mouse over the contacts variable, the DataTip will show you what the query returns. It's an IQueryable of "anonymous type", rather than an IQueryable of Contact types. Visual Basic and C#'s DataTips and debuggers often show different information. In this case, the difference is interesting as you can see in Figure 4-1 and Figure 4-2 Figure 4-1. The DataTip in Visual Basic shows the new contacts variable to be an IQueryable(Of )

Figure 4-2. The DataTip in C# shows even more details about the anonymous type

4.2.2.1. Anonymous Types The anonymous type is a new language enhancement introduced in Visual Basic 9 and C# 3.0 that allows the compilers to work with types that were not previously defined. Anonymous types are generally used for on-the-fly types that won't be used elsewhere in the application. It relieves you from having to define a class for every type, even if it is only to be used very briefly. Yet the returned anonymous type is still strongly typed which means that you can easily interact with it in the code following its creation.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 85

Return to Table of Contents

The sidebar Wrapping your head around Lambdas in Chapter 3 includes a link to an article by Anders Hejlsberg. The article also contains a great introduction to anonymous types. Anonymous types are a powerful new feature that can be used throughout .NET, but has special importance for LINQ queries because of its ability to allow projections that can return anything dreamt up by a developer. So this query returned an anonymous type that doesn't have a name, but has the properties Title, FirstName and LastName. If you are still modifying the earlier query method, you can see a bit of this magic by removing the Console.WriteLine method and retyping it. The anonymous type is strongly typed and recognized by Intellisense. Pretty cool!

Anonymous Types and Updates While later chapters will introduce the concepts of tracking changes to entities and performing updates to the database, it is important to keep in mind that this only takes place with complete entities. Anonymous types do not participate in change tracking or updates. The same is true of the data that results from randomly projected properties in ObjectQueries. Pay attention to projections to make note of where complete entities are returned versus anonymous types.

4.2.2.2. Implicitly Typed Local Variables Another new compiler trick that you have been taking advantage of in the code samples so far is the use of implicitly typed local variables. In C#, this is used with a new keyword, var and in VB, the pre-existing Dim keyword. It is possible to declare variables without identifying their types. They will infer the type based on the value that is being set. Hasn't it always seemed redundant to say something like Dim str as String="this is some text" or int MyInt=123? With implicitly typed local variables Dim str="this is some text" and var MyInt=123 is enough. In the case of replacing "int" with "var" the benefit is not very obvious. Had that type been MyCustomType then suddenly var looks pretty convenient.

NOTE

This shortcut is not always a good thing. It does remove some of the explicitness of your code. I wrote a blog post on DevSource.com titled "How Visual Studio 2008

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 86

Return to Table of Contents

made me even lazier". (http://blogs.devsource.com/devlife/content/ net_general/how_visual_studio_2008_made_me_even_lazier.html). There is an interesting discussion in the comments about the pros and cons of implicit typing. Where these really shine, however, is with LINQ query projections because there's no way to say "Dim contacts as a thing with a title, a firstname and a lastname". Instead you can write "Dim contacts (and just look at the other side of the equals sign to figure what this is)". Dim in VB and var in C# essentially translate to "thing". Run the application and you'll see that once again, the results are the same as they have been previously.

NOTE

When you learn more about Object Services and all of the functionality it provides to objects returned by queries against the Entity Data Model, you will better understand the significance of returning anonymous types rather than entire entity objects defined by the EDM.

4.2.2.3. Implicit and explicit anonymous type creation There are a number of ways to project into anonymous types. It is possible to give a name to this anonymous type such as ContactName in this example. Example 4-2. Naming a projected anonymous type in LINQ VB From c In context.Contacts _ Where c.FirstName = "Robert" _ Select ContactName = New With {c.Title, c.LastName, c.FirstName} C# var contacts = from c in context.Contacts where c.FirstName == "Robert" let ContactName = new {c.Title, c.LastName, c.FirstName} select ContactName;

C# does not allow naming in the SELECT statement has another operator, LET for this purpose.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 87

Return to Table of Contents

NOTE

There are so many ways to do projection and use anonymous types in LINQ queries. What you are seeing here is just a small slice of what can be achieved so be sure to look to the dedicated LINQ resources to expand your understanding. Naming the anonymous type is more useful if this new type is a property of the projected results. In Example 4-3, a projection is used to project much more than some strings. It creates a new type with another anonymous type as the first property and the Addresses of the contact as the second.

NOTE

Projecting the Addresses property is used here to highlight the projection. You'll learn more about working with related data later on in this chapter. By naming the anonymous type, the resulting property will have the name specified in the query. Notice that the property name is used later in the query for the Order By operator and when working with the results. Example 4-3. Anonymous types as properties VB Dim contacts = From c In context.Contacts _ Where c.FirstName = "Robert" _ Select _ ContactName = New With { _ c.Title, c.LastName, c.FirstName}, _ c.Addresses _ Order By ContactName.LastName For Each contact In contacts Dim name = contact.ContactName Console.WriteLine("{0} {1} {2}", _ name.Title.Trim, name.FirstName.Trim, _ name.LastName.Trim) Next C# var contacts = from c in context.Contacts where c.FirstName == "Robert" let foo= new { ContactName = new {c.Title, c.LastName, c.FirstName}, c.Addresses } orderby foo.ContactName.LastName select foo; foreach (var contact in contacts) { var name = contact.ContactName; Console.WriteLine("{0} {1} {2}",

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 88

Return to Table of Contents

name.Title.Trim(), name.FirstName.Trim(), name.LastName.Trim()); }

NOTE

Unlike the ContactName anonymous type in this query, the complete Address entities that are also returned from this query will participate in the change tracking and database updates.

4.2.3. Projections with LINQ Query Methods To project using LINQ's method based query syntax, you would use the Select method then identify the properties you want in its parameter. The method based query syntax requires the explicit syntax for creating an anonymous type in the predicate. In VB that definitely starts to get a bit clunky. Example 4-4. Projecting using LINQ's Method-based syntax VB context.Contacts _ .Where(Function(c) c.FirstName = "Robert") _ .Select(Function(c) New With {c.Title, c.LastName, c.FirstName}) C# context.Contacts .Where((c) => c.FirstName == "Robert") .Select((c) => new {c.Title, c.LastName, c.FirstName})

4.3. Projections in Entity SQL You can use projections with Entity SQL queries in both Object Services and EntityClient queries. Only LINQ queries can return anonymous types. Object Services has its own way of resolving projections when the resulting type doesn't exist. Because EntityClient does not attempt to materialize objects from the results, this is not a concern with EntityClient queries. When projecting with Object Services, the query will return data records. These are the same DbDataRecords returned by EntityClient queries. First let's look at the code and then at the resulting data. Here is where you will begin to benefit from having changed the name of the EntityContainer to PEF.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 89

Return to Table of Contents

Example 4-5. Projection with Entity SQL VB Dim queryStr = "SELECT c.FirstName, c.LastName, c.Title " & _ "FROM PEF.Contacts AS c " & _ "WHERE c.FirstName='Robert'" Dim contacts = PEF.CreateQuery( _ Of System.Data.Common.DbDataRecord)(queryStr) C# var queryStr = "SELECT c.FirstName,c.LastName, c.Title " + "FROM PEF.Contacts AS c " + "WHERE c.FirstName='Robert'"; var contacts = context.CreateQuery(queryStr);

Notice that in the Entity SQL string, the keyword VALUE is gone. That's because the projection is selecting multiple values. Also, note that the type being passed into the CreateQuery method is now a DbDataRecord. In the introduction to EntityClient in Chapter 3 you learned that a DbDataRecord represents a record in a DbDataReader. Therefore you will need to interact with these results in the same fashion that you did when using the EntityClient example. There is one very nice difference however. The results are not being streamed; they have been materialized into the DbDataRecord. Therefore you can access the resulting column data in any order that you want. That's why the query string selected FirstName, LastName and then Title. When you build the code to display the results, shown in Example 4-6, you'll see that it's okay to use Title first. Example 4-6. Enumerating through the DbDataRecord returned by a LINQ projection VB For Each c In contacts Console.WriteLine("{0} {1} {2}", _ c.Item("Title").ToString.Trim, _ c.Item("FirstName").ToString.Trim, _ c.Item("LastName").ToString.Trim) Next C# foreach (var item in contacts) { Console.WriteLine("{0} {1} {2}", item["Title"].ToString().Trim(), item["FirstName"].ToString().Trim(), item["LastName"].ToString().Trim()); }

NOTE

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 90

Return to Table of Contents

In this example, I used the alternate way of pulling data from a DbDataRecord. Item takes a string parameter (the column name) or an integer (the column position), whereas the GetString, GetInt and other related methods take only an integer as a parameter.

4.3.1. DbDataRecords and non-scalar properties 4.3.1.1. DbDataRecords and non-scalar properties Most of these examples project strings, though you saw one example with LINQ for Entities where an Addresses EntityCollection was projected. How would you interact with a DbDataRecord which contains an entity or another object in its columns? This Entity SQL expression selects the entire contact entity as the first property of the results and the count contact's Addresses as the second property. Example 4-7. Projecting Objects with EntitySQL VB Dim queryStr = "SELECT c,c.Addresses.Count " & _ "FROM PEF.Contacts AS c " & _ "WHERE c.FirstName='Robert'" Dim contacts = context.CreateQuery(Of DbDataRecord)(queryStr) For Each c In contacts Dim contact = CType(c.Item(0), Contact) Console.WriteLine("{0} {1} {2}", _ contact.Title, _ contact.FirstName, _ contact.LastName) Next C# var queryStr = "SELECT c,c.Addresses.Count " + "FROM PEF.Contacts AS c " + "WHERE c.FirstName='Robert'"

In the Example 4-6, you had to explicitly cast the items of the results to String types. In this case, because you know that the first item will contain a Contact type, you can cast the column to Contact and then work directly with that strongly typed object as shown in

4.3.1.2. Projecting with Query Builder Methods Example 4-8 shows an example of using a Query Builder method to do the projection. In the projection, you use the "it" alias to access the properties.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 91

Return to Table of Contents

Example 4-8. Using Query Builder methods to project data VB Dim contacts = context.Contacts _ .Where("it.FirstName='Robert'") _ .Select("it.Title, it.FirstName, it.LastName") C# var contacts = context.Contacts .Where("it.FirstName='Robert'") .Select("it.Title, it.FirstName, it.LastName");

Projection with Query Builder Methods also returns DbDataRecords. You'll need to access the results through the data record's items as with the other examples.

4.4. Querying Across Associations One of the big benefits that the Entity Data Model lends to querying is that the relationships are built into the model and you won't have to construct joins very often to access related data. Additionally, when using LINQ for the queries, the related data is presented via Intellisense which makes it very discoverable. Using the model, let's take a look at some more queries, this time digging into the associations. The model only has one association between Contact and Address. The association provides two navigations – one from Contact to all of its related Addresses and one from Address to its related Contact.

Navigations point to a Related End When working with Navigation properties in EntityObjects, the property begins as a Related End. This is an Entity Framework interface. Then EF, determines if the Related End should be an EntityObject or an EntityCollection. When the end is an Entity, Entity Framework takes two steps. First it populates the property (e.g. Address.Contact) with an actual object. Next it creates a second property to contain some metadata about the relationship. This property has the name of the navigation property plus the word Reference, e.g. ContactReference. When the end is an EntityCollection, the runtime will create an EntityCollection object and fill it with the related data. In the case of Contact.Addresses, the Addresses property will then be an EntityCollection of Address types. There is no additional Reference property created.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 92

Return to Table of Contents

Chapter [X], Relationships and Associations, drills much more deeply into this topic. In most cases, you will not be returning a collection of a single previously defined type. When the type doesn't pre-exist, LINQ to Entities will return anonymous type and many of these queries will return anonymous types. Because ObjectQueries can't return anonymous types, in these cases they will return the DbDataRecord type that you learned about in Chapter 3 in the EntityClient discussion. You can easily do projection drilling into related entities, although drilling into a collection is different than drilling into a reference entity. For example, you can't really do a query that requests Contact.Addresses.Street. Contact to Addresses is a one-to-many relationship and Addresses is a collection, not a single entity. Street is not a property of the Addresses EntityCollection. However, you could select Address.Contact.LastName, because you would be navigating to a single entity. There is only one contact per address; therefore there is no question as to which entity to retrieve the LastName from.

4.4.1. Navigation to an EntityReference Recall that when navigating to the "one" end of a one-to-one or many-to-one relationship, this is referred to as a Navigation Reference. The entity that you are pointing to is referred to as an EntityReference or EntityRef.

NOTE

Chapter [X] on Relationships and Associations will drill further into EntityRefs, EntityCollections and how they are surfaced as Navigation Properties. The following LINQ query returns an anonymous type containing an Address and its related Contact. Example 4-9. Projecting into an Entity Ref with LINQ to Entities VB Dim newTypes = From a In context.Addresses _ Where a.CountryRegion = "UK" _ Select New With {a, a.Contact} C# var newTypes = from a in context.Addresses where a.CountryRegion == "United Kingdom" select new { a, a.Contact };

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 93

Return to Table of Contents

Figure 4-3 displays the resulting complex type in the debugger where you can see that one property is the Address record and the other is the Contact. Figure 4-3. The query results contain a complex type with the Address and its Contact.

When working with the results, you'll have to drill into the new type's properties (the Address and the Contact) and from there, drill into their properties as in Example 4-10. Example 4-10. Accessing the properties of an anonymous type VB For Each newtype In newTypes Console.WriteLine("{0} {1} {2}", _ newtype.Contact.LastName, _ newtype.a.Street1, newtype.a.City, ) Next C# foreach (var newtype in newTypes) { Console.WriteLine("{0} {1} {2}", newtype.Contact.LastName, newtype.a.Street1, newtype.a.City); }

NOTE

The first property is named "a" because it is using the variable name given in the query. If you want to be sure the property is called "Address" you can use that instead of the simpler "a" or use a LINQ feature to rename the property. VB: Select New With {.Address = a, a.Contact} C#: select new {Address= a, a.Contact };

Then you can work with newtype.Address in the resulting data. The same query in Entity SQL looks like this: Example 4-11. Projecting into an Entity Ref with Entity SQL SELECT a,a.Contact FROM PEF.Addresses AS a WHERE a.CountryRegion='Canada'

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 94

Return to Table of Contents

When working with these results you can cast the data in the first position to an Address and the data in the second position to a Contact as you did in Example 4-7. While this may suit many scenarios in your applications, you may prefer to project individual properties to create a type that is not complex. This is also possible as you are not limited to only projecting entire reference entities. Example 4-12 shows such a query using LINQ to Entities. This projection returns a new type with three properties. The first is an Address entity; the second and third are Strings. Again, the property names are based on the query defaults — a, FirstName and LastName. Example 4-12. Projecting into an Entity Ref and returning unshaped data VB Dim newTypes = From a In context.Addresses _ Where a.CountryRegion = "UK" _ Select New With {a, a.Contact.FirstName, _ a.Contact.LastName} For Each newtype In newTypes Console.WriteLine("{0} {1} {2} {3}", _ newtype.a.Street1, newtype.a.City _ newtype.FirstName, newtype.LastName) Next C# var newTypes = from a in context.Addresses where a.CountryRegion == "United Kingdom" select new { a, a.Contact.FirstName, a.Contact.LastName }; foreach (var newtype in newTypes) { Console.WriteLine("{0} {1} {2} {3}", newtype.FirstName, newtype.LastName, newtype.a.Street1, newtype.a.City); }

4.4.2. Filtering and sorting with an EntityReference You can filter and sort based on a property of an EntityReference even if you are not selecting the related data. For example, you can select all addresses for contacts with a particular last name. This LINQ to Entities query in Example 4-13 sorts by Contact.Lastname and filters on the Contact.AddDate field even though AddDate is not part of the results. Example 4-13. Filter and Sort on Reference properties VB From a In context.Addresses _ Where a.Contact.AddDate > New Date(2008, 1, 1) _ Order By a.Contact.LastName _ Select New With {a, a.Contact.FirstName, a.Contact.LastName}

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 95

Return to Table of Contents

C# from a in context.Addresses where a.Contact.AddDate > new System.DateTime(2008, 1, 1) orderby a.Contact.LastName select new {a, a.Contact.FirstName, a.Contact.LastName};

In Entity SQL, the same query would be represented as SELECT a,a.Contact.FirstName,a.Contact.LastName FROM PEF.Addresses AS a WHERE a.Contact.AddDate>DATETIME'2007-01-1 00:00' ORDER BY a.Contact.LastName"

NOTE

That very odd syntax for the date in the WHERE clause parameter is Entity SQL's way of expressing a DateTime value. See the sidebar ESQL Literals for more information.

Entity SQL Literals Literals are a way to express a value. A string is easily expressed by wrapping quotes around it. But how, in Entity SQL can you express a date? The DateTime literal solves this problem. January 1, 2008 is expressed in Entity SQL as DATETIME'2007-01-1 00:00'. Other types that use literal keywords in Entity SQL are Time, GUID, BINARY and DATETIMEOFFSET. Check the MSDN Library topic "Literals (Entity SQL) for more details about expressing values in Entity SQL

4.4.3. Navigating to Entity Collections Querying with related data is straight forward when the related data is a single entity, but what about when the navigation property is an EntityCollection such as Contact.Addresses. Let's start with a simple scenario that you have seen a few times already in this chapter, returning a contact and it's collection of addresses. To highlight the difference between the original properties and the results, the EntityCollection in the new type is given a random name.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 96

Return to Table of Contents

Example 4-14. Projecting an Entity Collection with LINQ VB Dim contacts = From c In context.Contacts _ Select New With {c, .Foos = c.Addresses} C# var contacts =

from c in context.Contacts select new {c, Foos = c.Addresses};

This query creates a new anonymous type with two properties. The first is the Contact and the second is the EntityCollection of Addresses related to that Contact. You can then enumerate through the results and then for each result, enumerate through the collection inside of the Address property as in Example 4-15. Example 4-15. Enumerating over shaped data that includes an EntityCollection VB For Each contact In contacts Console.WriteLine("{0}: Address Count {1} ", _ contact.c.LastName.Trim, contact.Foos.Count) For Each address In contact.Foos Console.WriteLine(" City= {0}", address.City) Next Next C# foreach (var contact in contacts) { Console.WriteLine("{0}: Address Count {1} ", contact.c.LastName.Trim(), contact.Foos.Count); foreach (var foo in contact.Foos) { Console.WriteLine(" City= {0}", foo.City); } }

You may not want the Addresses to be represented as a separate property in your resulting data but there are many ways to shape query results and right now the goal is to get a view of what these queries can achieve.

4.4.4. Projecting Properties from EntityCollection Entities If you wanted to select particular properties such as Street and City from each Address of Contacts, the method you choose to query depends on what shape you would like the results to be.

4.4.4.1. Shaped results You could shape the data similar to the previous example with the difference that instead of a set of complete address entities as the Foos property, you can project some of the address properties. This would result in a set of anonymous types, named StreetsCities instead of Foos, in the second property. Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 97

Return to Table of Contents

The way to achieve this is to do a nested query — a feature we'll look at more closely further on in the chapter. You can see in the following query that the third property, StreetsCities, contains the results of querying the Contact's Addresses. Example 4-16. Projecting values from an EntityCollection VB From c In context.Contacts _ Select New With {c.FirstName, c.LastName, _ .StreetsCities = From a In c.Addresses Select a.Street1, a.City} C# from c in context.Contacts select new { c.FirstName, c.LastName, StreetsCities = from a in c.Addresses select new { a.Street1, a.City } }

The resulting anonymous type has the properties FirstName, LastName and a collection of anonymous types with Street and City properties. The new type is displayed in the debugger screenshot in Figure 4-4. Figure 4-4. The newly shaped anonymous type

4.4.4.2. Flatten the Results Another way to project into the Addresses is to merely turn the query around. Query the addresses and their contact data to flatten the results as in Example 4-17 so that the data is no longer shaped. Example 4-17. Flattening the related data VB From a In context.Addresses _ order By a.Contact.LastName _ Select New With {a.Contact.FirstName, a.Contact.LastName, _ a.Street1, a.City} C# var contacts = from a in context.Addresses orderby a.Contact.LastName select new {a.Contact, a.Contact.LastName, a.Street1, a.City};

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 98

Return to Table of Contents

This will result in a single type with four properties, but contacts with multiple addresses will appear multiple times as you can see in this section of the results. Katherine Harding and Keith Harris each have two results. Hanson, John: 825 W 500 S, Bountiful Harding, Katherine: 52560 Free Street, Toronto Harding, Katherine: 25 Flatiron Blvd, Vancouver Harrington, Lucy: 482505 Warm Springs Blvd., Fremont Harris, Keith: 3207 S Grady Way, Renton Harris, Keith: 7943 Walnut Ave, Renton Harui, Roger: 9927 N. Main St., Tooele Hass, Ann: Medford Outlet Center, Medford

4.4.5. Filtering and Sorting with EntityCollections While you can easily use related data in projections or for filtering, sorting and other operations, it is important to keep in mind that when you that related data is in a collection, you need to leverage operations which can be performed on a set of data. For example, if you want to find contacts with addresses in the UK , you can use LINQ to Entities' ANY method or Entity SQL's EXISTS operator to search the contact's Addresses. The LINQ query uses a predicate to provide the condition for ANY. Example 4-18. Filter condition provided by an Entity Collection with LINQ VB From c In context.Contacts _ Where c.Addresses.Any(Function(a) a.CountryRegion = "UK") _ Select c C# from c in context.Contacts where c.Addresses.Any((a) => a.CountryRegion == "UK") select c;

Entity SQL's EXISTS is not quite as facile as the ANY method. You'll need to pass a subquery into EXISTS so that it knows what to search. Look closely at the subquery in Example 4-19. It is querying c.Addresses, which is the collection of Addresses that belongs to the value being returned in the main query. The subquery is able to take advantage of the navigation from a Contact to its Addresses. Example 4-19. Filtering across a navigation with Entity SQL queryString = "Select VALUE c " & _ "FROM PEF.Contacts as c " & _ "WHERE EXISTS(SELECT a from c.Addresses as a " & _ "WHERE a.CountryRegion='UK')"

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 99

Return to Table of Contents

4.4.6. Aggregates with EntityCollections Aggregates perform calculations on a series of data – count, sum, average, min, max, etc. You may not want the entire collection of addresses, but some aggregated information about that collection.

4.4.6.1. Aggregates in LINQ to Entities It's relatively simple with LINQ, using one of the aggregate methods, such as Count which you can add as a method on a collection. The Count method will return the count of the items in the collection. Example 4-20. Using the Count aggregate method in LINQ to Entities VB From c In context.Contacts _ Select New With {c.LastName, c.Addresses.Count} C# from c in context.Contacts select new {c.LastName, c.Addresses.Count};

Other types of aggregates, such as Max, require a specific value to aggregate. You can supply that value using a lambda expression. Example 4-21. Using an aggregate method with a predicate in LINQ VB From c In context.Contacts _ Select New With {c.LastName, _ .MaxPC = c.Addresses.Max(Function(a) a.PostalCode)} C# from c in context.Contacts select new { c.LastName, MaxPC = c.Addresses.Max((a) => a.PostalCode)};

It's important to name the property returned by the aggregate function because LINQ is unable to derive one based on the method. If you forget to do this, both VB and C# will give a compiler error explaining the problem.

NOTE

Visual Basic has an Aggregate operator for LINQ that can be used in place of FROM in your LINQ queries. Check the MSDN Library topic, "Aggregate Clause (Visual Basic)", for more information.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 100

Return to Table of Contents

4.4.6.2. Aggregates in Entity SQL Working with the aggregates is not quite as simple with Entity SQL. For example, LINQ is able to count the elements in a collection and doesn't care if the collection contains values or objects. But Entity SQL can only perform aggregates on a collection of values and even then, only certain types of values. This actually lines up with how SQL Server uses aggregates as well. Therefore with Entity SQL you can't write Count(c.Addresses), but need to pass a value, such as AddressID in to the Count function. To do this, you can use a subquery against c.Addresses which returns a collection of AddressIDs. You can then COUNT the results of that query. Example 4-22. Using the Count aggregate function in Entity SQL Select c, COUNT(Select VALUE a.AddressID FROM c.Addresses as a) FROM PEF.Contacts as c

The other aggregates work in the same way. Here is the MAX query written with Entity SQL. Example 4-23. Using the MAX aggregate function in Entity SQL SELECT c.LastName, MAX(SELECT VALUE a.PostalCode FROM c.Addresses AS a) FROM PEF.Contacts AS c

You can even use an aggregate in a subquery as in Example 4-24. Example 4-24. Aggregate in a subquery SELECT c.LastName, (SELECT VALUE MAX(a.PostalCode) FROM c.Addresses as a) FROM PEF.Contacts AS c

The second column of the query results does not contain the string value of the PostalCode. It contains the results of a query and therefore it is a collection of string values. You can use code similar to Example 4-15 or use a SET operator.

4.4.7. Entity SQL SET Operators Like aggregates, SET operators work with a set of values. The ANYELEMENT set operator will randomly pick an element from a collection. You can even use this with collections that contain only one element, such as the MAX PostalCode column in the previous example.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 101

Return to Table of Contents

Example 4-25. Using the ANYELEMENT operator against a set of data. SELECT c.LastName, ANYELEMENT(SELECT VALUE max(a.PostalCode FROM c.Addresses AS a) FROM PEF.Contacts AS c

The results of this query will now contain a string in the second position, not a collection. The SET operators in Entity SQL are ANYELEMENT, EXCEPT, FLATTEN, INTERSECT, EXISTS and NOT EXISTS, IN and NOT IN, OVERLAPS, SET and UNION. There is also an ELEMENT operator that has not yet been implemented but is reserved. If you attempt to use it in V1, you will get an exception that explains ELEMENT cannot be used yet. EXISTS or NOT EXISTS is useful for determining if an entity has any items in a child collection. Example 4-26 shows a query that returns only those contacts who have any Addresses. Example 4-26. Using EXISTS to filter on the existence of child data SELECT VALUE c from PEF.Contacts AS c WHERE EXISTS(SELECT a FROM c.Addresses AS a)

NOTE

Take some time to explore these operators in the documentation and in code to get a feel for where and when you might want to use them.

4.4.8. Aggregates in LINQ Methods and Query Builder Methods The LINQ aggregates are methods, not query operators. Therefore they work very naturally the LINQ Query Methods. Example 4-27 uses the Max aggregate as one of two projected values to be returned. Example 4-27. A LINQ Method Syntax query using an aggregate VB context.Contacts _ .Select(Function(c) New With {c.LastName, _ .MaxCode = c.Addresses.Max(Function(a) a.PostalCode)}) C# context.Contacts .Select((c) => new { c.LastName, MaxCode = c.Addresses.Max((a) => a.PostalCode) });

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 102

Return to Table of Contents

This query does two interesting things. First it uses a lambda expression to specify what values should be selected. Once the variable has been declared, the function projects and anonymous type consisting of LastName as the first property and MaxCode as the second. MaxCode is defined by using the Max aggregate on the Addresses collection of the contact. The Query Builder methods do not provide aggregate methods. However, you can actually use an Entity SQL query as the argument of the SELECT query builder method to perform the aggregate. Remember that the collection being queried in the subquery is based on the main query's control variable, referred to with the "it" alias by default. Here is the same query from Example 4-27 expressed with Query Builder methods. Example 4-28. An Entity SQL Query Builder method using an aggregate VB context.Contacts _ .Select("it.LastName, " & _ "( MAX(SELECT VALUE a.PostalCode FROM it.Addresses AS a))") C# context.Contacts .Select("it.LastName, " + "( MAX(SELECT VALUE a.PostalCode FROM it.Addresses AS a))");

4.5. Joins and Nested Queries While associations in the Entity Data Model minimize the need for Joins in queries, there may be times when a relationship exists, but there is no association to represent the relationship. In these and other cases you can use nested queries or Joins to bring the data together.

Should you even use JOINS? Zlatko Michailov, the Entity SQL Program Manager at Microsoft, writes in his blog: "A well defined query against a well defined entity data model does not need JOIN. Navigation properties in combination with nesting sub-queries should be used instead. These latter constructs represent task requirements much more closely than JOIN does." (http://blogs.msdn.com/esql, November 1, 2007 post) LINQ to Entities provides a JOIN operator as well as GROUPJOIN. Entity SQL provides a variety of options in the JOIN FROM clause including inner joins, left, right and full outer joins. It also enables joining multiple collections separated by commas. Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 103

Return to Table of Contents

4.5.1. Joins The vOfficeAddresses entity in the current model has all of the contact properties except for the contact's Title. Because there is no association between vOfficeAddress and Contact, you will need to use JOIN to combine the vOfficeAddress entity properties with the Title property.

NOTE

You could, of course, add the association to the model in this case, but then there would be no lesson here, would there? Example 4-29 shows the syntax of a LINQ JOIN. Example 4-29. JOIN syntax for LINQ FROM [variableA] IN collectionA JOIN [variableB] IN collection ON variable.commonproperty EQUALS variableB.commonProperty SELECT .....

Example 4-30 shows how to combine data from Contact entities and vOfficeAddress entities using the JOIN. Example 4-30. A LINQ to Entities query using a JOIN VB From con In PEF.Contacts _ Join add In PEF.vOfficeAddresses _ On con.ContactID Equals add.contactID _ Select New With {add.FirstName, add.LastName, _ con.Title, add.Street1, add.City, add.StateProvince} C# from c in context.Contacts join oa in context.vOfficeAddresses on c.ContactID equals oa.ContactID select new { oa.FirstName, oa.LastName, c.Title, oa.Street1, oa.City, oa.StateProvince };

This provides an inner join where only entities with matching ContactIDs are returned. Any contacts with no match in the vOfficeAddresses will not be returned nor will vOfficeAddresses with no match in Contacts. The syntax of an Entity SQL JOIN is shown Example 4-31.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 104

Return to Table of Contents

Example 4-31. JOIN syntax for Entity SQL SELECT variableA, variableB FROM collection as variableA JOIN Collection as variableB ON Property = Property

NOTE

Entity SQL has the ability to do CROSS JOINs. You can express them explicitly; however a JOIN without an ON clause will implicitly become a CROSS JOIN, pairing every entity in the first collection with every entity in the second collection. So watch out! Example 4-32 demonstrates the same JOIN query expressed in Entity SQL Example 4-32. An Entity SQL query using JOIN SELECT c.Title,oa.FirstName, oa.LastName, oa.Street1, oa.City, oa.StateProvince FROM PEF.Contacts as c JOIN PEF.vOfficeAddresses as oa ON c.ContactID = oa.ContactID

4.5.2. Nested Queries Both LINQ and Entity SQL provide the ability to nest queries and you have already seen some examples of this. When you write a query, any place where a value is expected, you can use another query in its place, as long as that query returns an acceptable type. A nested query can be used in place of an expression or a collection as you will see in the following examples. The goal of the JOIN queries above was to return properties from a contact entity combined with properties from the vOfficeAddress entities where the ContactID matches.

4.5.2.1. Using a Nested LINQ Query as a projection Example 4-33 shows how to express the above query in LINQ using a nested query instead of the JOIN. This query uses a nested query (which is highlighted) combined with the FirstOrDefault method in place of a projected value to return results from vOfficeAddresses. Example 4-33. Nested Query in place of a SELECT expression in LINQ VB From a In context.vOfficeAddresses _

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 105

Return to Table of Contents

Select New With {a.FirstName, a.LastName, _ .Title = (From c In context.Contacts _ Where c.ContactID = a.ContactID _ Select c.Title).FirstOrDefault, _ a.Street1, a.City, a.StateProvince} C# from a in context.vOfficeAddresses select new { a.FirstName, a.LastName, Title = (from c in context.Contacts where c.ContactID == a.ContactID select c.Title).FirstOrDefault(), a.Street1, a.City, a.StateProvince }

There are a few notable twists to this query. The first should be familiar; an anonymous type is not able to automatically name the return from the nested query. Therefore it is given the name "Title". The subquery returns an IQueryable of String, not just a string, which is why the FirstOrDefault method is appended to the query..

4.5.2.2. Using a Nested LINQ Query as the Collection to be queried You can also use the nested query in place of the collection being queried. The nested query merely returns another collection to be queried. For example, rather than querying all vOfficeAddresses, you could create a sub query that returns only vOfficeAddresses in Ontario and then query against that. The following example is simplistic and could easily be expressed without the nested query. The technique can be useful when you have much more complex queries that you are attempting to express. Example 4-34. Nested Query in place of a target collection in LINQ VB Dim contacts = From add In _ (From oa In PEF.vOfficeAddresses _ Where oa.StateProvince = "Ontario" Select oa) _ Select ... C# var contacts = from add in (from oa in PEF.vOfficeAddresses where oa.StateProvince == "Ontario" select oa) select ...

You can benefit from using nested queries to help with complicated queries by separating the nested query from the main query. Example 4-35 ties a subquery to a variable and then uses that variable in another query. This can make the code much more readable. When the query is executed, Entity Framework will create a single query from the combined expressions.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 106

Return to Table of Contents

Example 4-35. Breaking a nested query out of the main query in LINQ VB Dim subquery = From oa In PEF.vOfficeAddresses _ Where oa.StateProvince = " Ontario" Select oa Dim contacts = From add In subquery _ Select ....

NOTE

You can't separate out a nested query that's inside of a projection, as in Example 4-33 because its filter condition is dependent on the main query.

4.5.2.3. Nested Queries in Entity SQL With Entity SQL, the nested query works in the same manner using the query in place of an actual value, though there's no need to name the property it represents. Example 4-36. Nested Query in place of a SELECT expression in Entity SQL SELECT oa.FirstName, oa.LastName, ANYELEMENT(SELECT VALUE c.Title FROM PEF.Contacts as c WHERE c.ContactID=oa.ContactID), oa.Street1, oa.City, oa.StateProvince FROM PEF.vOfficeAddresses as oa

The following query demonstrates replacing the queried collection with a nested query. Example 4-37. Nested Query in place of a FROM expression in Entity SQL SELECT oa.FirstName, oa.LastName FROM (SELECT VALUE oa FROM PEF.vOfficeAddresses AS oa WHERE oa.StateProvince='Ontario') AS add

This can easily be broken up for readability because you are merely building strings; the queries can be concatenated together. Example 4-38. Breaking up a nested query in Entity SQL subQuery = "SELECT VALUE oa " & _ "FROM PEF.vOfficeAddresses AS oa " & _ "WHERE oa.StateProvince='Ontario'" queryString = _ "SELECT add.FirstName, add.LastName FROM (" & subQuery & ") as add"

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 107

Return to Table of Contents

Note that an Order operator in a subquery will be ignored. The main query controls ordering.

4.6. Grouping Both LINQ and Entity SQL provide operations for grouping data. You can use grouping in connection with aggregates or to shape data. LINQ to Entities has a Group operator (literally Group By in Visual Basic and Group in C#) and a GroupBy method (with eight overloads). Entity SQL provides a GROUP BY operator and a GroupBy Query Builder method. The results of the grouping can use automatic naming and in other cases can be explicitly named. An INTO GROUP clause is required in Visual Basic. C# has an option INTO clause. The constructs for VB and C# are quite different and easiest to explain with examples. Example 4-39 shows the simplest form of grouping in LINQ for both Visual Basic and C#. Example 4-39. Simple Grouping in LINQ to Entities VB From c In PEF.Contacts Group By c.Title Into Group C# from c in PEF.Contacts group c by c.Title into mygroup

The result of this query is an IQueryable of anonymous types. The anonymous types contain two properties, one containing the Title and another containing the collection of Contacts that go with that Title. The VB query automatically named the property containing the Title as "Title" as shown in Figure 4-5. Figure 4-5. The VB result contains a Title property and a Group property. The Group property contains three Contacts

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 108

Return to Table of Contents

By default C# uses "Key" as the name of the grouping property and doesn't name the property that contains the grouped records as you can see in Figure 4-6. Figure 4-6. C# Grouping doesn't name properties very well by default

VB allows you to specify the property name rather than use the default. In Visual Basic, to change the Title property of the above query to MyTitle, the syntax would be "Group By MyTitle=Title". C# does not allow this using the defaults. In VB, the Group property is available to access the group. This can be renamed as well. For example "Into MyGroup = Group" renames the property to MyGroup.

4.6.1. Naming properties when Grouping 4.6.1.1. Naming properties when Grouping C#'s optional INTO clause allows you to specify a group name, but this is not exposed as a property. Specifying the name with INTO is so that you can perform further functions on the group. Note that in C#, using the INTO clause requires that you also use the SELECT clause. The key property is then accessible as a property of the group. With the group specified, it is now possible to explicitly name the properties in C#. LINQ queries in Visual Basic will imply a SELECT statement if it is not used. In this case, the query will still return Title and MyGroup by default without specifying SELECT. Of course, you can shape the data further by specifying your own output with an explicit SELECT operator. The following demonstrate these changes to the previous queries. Example 4-40. LINQ Group By with explicitly named Groups and targets VB From c In context.Contacts _ Group By c.Title Into MyGroup = Group C# from c in context.Contacts group c by c.Title into MyGroup orderby MyGroup.Key select new {MyTitle = MyGroup.Key, MyGroup};

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 109

Return to Table of Contents

4.6.1.2. Chaining Aggregates Visual Basic provides a simple way to use aggregates in grouping queries, by specifying one or more aggregates in the INTO clause separated by commas. In this example, your result will contain the properties Max and Count. Example 4-41. Chained Aggregates in VB LINQ VB From con In context.Contacts _ Group By con.Title Into MyGroup = Group, _ Max(con.AddDate), Count()

In C#, you need to explicitly project these properties in the Select clause using methods and predicates as follows. Example 4-42. Combining Aggregates in C# LINQ C# from c in context.Contacts group c by c.Title into MyGroup orderby MyGroup.Key select new {MyTitle = MyGroup.Key, MyGroup, Max = MyGroup.Max(c => c.AddDate), Count = MyGroup.Count()}

4.6.1.3. Filtering on Group Conditions There is so much more that you can do with grouping in LINQ. For now, we'll take a look at one more variation— filtering on the grouping condition. The Title fields in the sample data contain Mr., Mrs. Ms., Sr. and a few others. There are also contacts with no title. Perhaps you would like to group on title, but exclude empty titles. To filter what is being grouped, such as "only group contacts with something in the title field", you can apply the filter to the control variable, Title, to make sure it contains a value. You may, however, want to filter on a property of the Group, however. With LINQ you can continue to use the WHERE operator as shown in Example 4-43. Example 4-43. Filtering on a Group property with LINQ VB From c In context.Contacts _ Group By c.Title Into MyGroup = Group, Count() _ Where (MyGroup.Count() > 150) C# from c in context.Contacts group c by c.Title into MyGroup

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 110

Return to Table of Contents

where MyGroup.Count() > 150 select new { MyTitle = MyGroup.Key, MyGroup, Count = MyGroup.Count()};

In LINQ, you will also need to be aware of variables going out of scope as in this query which won't even compile. The "a" in "Group by a .CountryRegion" is out of scope because by this point in the query, you are now working with the anonymous type returned by the Select statement. And, the Select does need to go before the Group by. Example 4-44. This VB query won't compile because "a" is out of scope in the Group by clause VB From a In context.Addresses _ Select a.Contact.FirstName, a.Contact.LastName, a.CountryRegion _ Group By a.CountryRegion Into MyGroup = Group, Count() _ Where (MyGroup.Count() > 150)

The query can be achieved by naming the anonymous type, then grouping by a field within the name. Example 4-45. Avoid variables going out of scope by naming them VB From add In PEF.Addresses _ Select c = New With {add.Contact.FirstName, add.Contact.LastName, _ add.CountryRegion} _ Group By c.CountryRegion Into MyGroup = Group C# from a in context.Addresses let c= new {a.Contact.FirstName, a.Contact.LastName, a.CountryRegion} group c by c.CountryRegion into MyGroup where (MyGroup.Count() > 150) select MyGroup;

Both the Visual Studio documentation and the ADO.NET Entity Framework documentation and samples can provide you with an astounding array of data shaping that can be performed with group by in LINQ and even then there are still many more.

4.6.2. Grouping in Entity SQL LINQ will spoil you with its grouping capabilities. Like SQL, Entity SQL comes with a lot of rules so that queries can be converted into a command tree and then into the provider's query syntax. For example, in SQL the most commonly encountered rule is that every expression in the SELECT must either be accounted for in the GROUP BY clause or be wrapped in an aggregate. The same is true in Entity SQL, which prevents you from being able to select

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 111

Return to Table of Contents

entire objects in the select clause. However, it is still possible to return entire objects and shape data in Entity SQL by putting the GROUP BY operator into a nested query. First take a look at some simple grouping in Entity SQL. Example 4-46. A simple GROUP By Example in Entity SQL SELECT c.Title, COUNT(c.Title) FROM PEF.Contacts as c GROUP BY c.Title

The two projected expressions in the SELECT are covered either by the GROUP By or an aggregate (COUNT). The query returns [blank] 6 Mr. 255 Ms. 177 Sr. 3 Sra. 2

To group on an expression that is evaluated, such as "Title" + c.Title, the grouping must be explicitly named and that name needs to be used as a projected expression. Example 4-48 shows the Entity SQL syntax for creating an expression and grouping on it in the same query. The expression, EvalTitle is built in the GROUP BY clause and the used by name in the SELECT. Example 4-47. Grouping by a calculated expression SELECT evalTitle,count(c.Title) FROM PEF.Contacts as c GROUP BY "Title: " +c.Title as evalTitle

4.6.2.1. Returning Entities from an Entity SQL Group By Query Now, let's take a look at how you can return full objects from Entity SQL when using GroupBy. The trick is in using nested queries. To reproduce the LINQ query that grouped by Title and returned each Title with its collection of contacts, you can use a nested query as an expression in the select statement. The query seems not to be required to follow the rule of being part of the GROUP BY clause or the target of an aggregate. Example 4-48. Example Caption Text Goes Here SELECT TCon.Title, (SELECT c FROM PEF.Contacts as c WHERE c.Title= TCon.Title) FROM PEF.Contacts as TCon GROUP BY TCon.title

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 112

Return to Table of Contents

The nested query returns a collection of Contacts whose Title property equals the current Title being returned by the group. While this looks like it might do some scary things on the server with respect to the generated SQL, the SQL is similar to the SQL created as a result of the first LINQ query in this section on Grouping.

4.6.2.2. Filtering based on Group properties You saw that LINQ uses the WHERE clause to filter within a group. In Entity SQL, you can use the HAVING clause for this purpose as shown in Example 4-49. Example 4-49. Entity SQL's HAVING clause helps with filtering SELECT groupCon.Title,count(groupCon.ContactID) FROM PEF.Contacts as groupCon GROUP BY groupCon.title HAVING count(groupCon.ContactID)>150

This returns only the title groups that contain more than 150 contacts. The results will be Mr. Ms.

255 177

Like everything else this chapter has covered so far, we have only skimmed the surface of GroupBy in Entity Framework queries. You will see more uses throughout this book and can find more details (and plenty of rules) in the documentation. The rest of this chapter will explain some important concepts that have been exposed by the queries you've seen so far.

LINQ Compiled Queries and ESQL Cached Queries One of the expensive processes of executing queries is in the query compilation. This is when the query is transformed into the proper query to be sent along to the database. LINQ to Entities has a feature called pre-compilation where you can compile a query in advance and access that compiled version as needed. Even if some of the query parameters change such as searching for LastName="Smith", the searching for LastName="Holbert", the pre-compiled query will be used. This has a huge impact on performance and Microsoft recommends that you use them for any queries that might be called repeatedly. Entity SQL has the ability to cache its queries and does this by default. The performance benefit is similar to that of using pre-compiled LINQ queries. Chapter 13, Making it Real, explores both of these features.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 113

Return to Table of Contents

4.7. Shaped data returned by queries Whether you write a query that returns entities, anonymous types, DbDataRecords or DbDataReaders, you can return shaped data. You've seen this in a number of the above queries, with a variety of shaped results. How you use this data depends on how it is shaped. Let's take a further look at the results of some of the above queries. The LINQ and Object Services queries that returned entities defined in the model are not shaped. They are purely a collection of individual entities.

NOTE

Queries can also return graphs of data. In a graph, the related data is contained in the entity, not separated out to another field in the results. You'll see examples of this later in the chapter. For example, Example 4-18 returned an IQueryable of Contacts. Example 4-14, however, returned an anonymous type with two properties. The first property was a Contact entity and the second was a collection of Address entities related to that Contact. The code in Example 4-15, enumerated over that data, albeit in a somewhat boring way, in order to demonstrate what the data looked like. It showed the Contacts and the Addresses but did not truly demonstrate the relationship between the two. The following example executes the same query then enumerates through the resulting anonymous types. This time, however, the code accesses the Addresses as a navigation property of the Contact. Example 4-50. LINQ query creating shaped results VB Using context As New PEF Dim contacts = From a In context.Addresses _ Where a.CountryRegion = "Canada" _ Select New With {a, a.Contact} For Each contact In contacts Console.WriteLine("{0}: {1} Addresses", _ contact.Contact.LastName, _ contact.Contact.Addresses.Count()) For Each address In contact.Contact.Addresses Console.WriteLine(" {0} {1}", address.Street1, address.City) Next Console.WriteLine() Next End Using C# static private void MOreSHapedDataTests()

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 114

Return to Table of Contents

{ using (PEF context = new PEF()) { var contacts = from a in context.Addresses where a.CountryRegion == "Canada" select new { a, a.Contact }; foreach (var contact in contacts) { Console.WriteLine("{0}: {1} Addresses", contact.Contact.LastName, contact.Contact.Addresses.Count()); foreach (var address in contact.Contact.Addresses) { Console.WriteLine(" {0} {1}", address.Street1, address.City); } Console.WriteLine(); } } }

The WriteLine method doesn't access the property "a" of the anonymous type, but instead, navigates to the addresses through the Contact property of the anonymous type.

4.7.1. Entity Framework connects the related data How was that possible? As the Contact and Address entities are materialized, Entity Framework recognizes that they are related to each other and wired them up so that you can navigate between the related entities. The Address objects have a Contact object in their Contact property and the Contact objects have Addresses in their Addresses property. This is a very high level explanation of an important function of Entity Framework's Object Services API which you will learn plenty about throughout the book. There is an interesting thing to be aware of with respect to how the Entity Framework connects the related entities in the scenario laid out in Example 4-50. If you look at the sample of the output below, you can see that there are two addresses that belong to the contact "Alderson". Both addresses are in Montreal. But the first instance says that Alderson only has one Address. It is not until the code has reached the second address that the contact is aware that two addresses exist in its Addresses navigation collection. City: Nepean, LastName: Allison LastName: Allison, # Addresses: 1 .....Nepean City: Montreal, LastName: Alderson LastName: Alderson, # Addresses: 1 .....Montreal City: Montreal, LastName: Alderson LastName: Alderson, # Addresses: 2 .....Montreal .....Montreal City: Montreal, LastName: Steelman LastName: Steelman, # Addresses: 1 .....Montreal

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 115

Return to Table of Contents

The reason that the second address isn't recognized initially is because it hasn't been materialized as an object yet. As the code enumerates through the query results for the first time, the objects are created from the query results as each one is reached. Once the second address is encountered and turned into an object, then its relationship to the Contact is identified. The object life cycle will be explored more deeply in a later chapter, but this should give you some idea for now about what's going in this example.

4.7.2. Shaped Data from Entity SQL As you've seen already, projections in Object Services result in DbDataRecords, as opposed to the anonymous types that LINQ returns. However, even in these DbDataRecords, you can still find complete entities and navigate through their associations. The same query above is expressed in Entity SQL in Example 4-51. Example 4-51. Entity SQL resulting in addresses with their contacts SELECT a,a.Contact FROM PEF.Addresses AS a WHERE a.CountryRegion='Canada'

This query results in an ObjectQuery of DbDataRecords which are structured as rows and columns. Each row in this result has two columns (also called fields). An Address entity is contained in the first field and a Contact entity is contained in the second field. Figure 4-7 shows the first column of one of the DbDataRecords in the results. The item is an Address entity. The second column contains a Contact entity. So even though it is a DbDataRecord, it still can contain known objects. Figure 4-7. The first column of each DbDataRecord results contains an Address entity.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 116

Return to Table of Contents

The code in Example 4-52 inspects the Address entity in the first field and the Contact entity in the second field. As with the LINQ example above, the contacts will not be aware of all of related Addresses until each of those addresses has been enumerated over. Also, though the Item property returns objects, thanks to implicitly typed local variables in VB9 and C#3, the compiler is able to know that c.Item("add") returns an Address entity and c.Item("Contact") returns a contact entity. With the strongly typed variables and the resulting Intellisense, it is easy to work with the objects. Example 4-52. Enumerating through and reading the shaped data from an ObjectQuery VB For Each record In addresses Dim address = CType(record.Item("a"), Address) Console.WriteLine("{0},{1}", _ address.City.Trim, _ address.Contact.LastName) Dim con = CType(record.Item("Contact"), Contact) Console.WriteLine("{0},{1}", con.LastName.Trim, _ con.Addresses.Count()) For Each a As Address In con.Addresses Console.WriteLine("....." & a.City) Next Console.WriteLine() Next C# foreach (var record in addresses) { var address = (Address)(record["a"]); Console.WriteLine("{0},{1}", address.City.Trim(), address.Contact.LastName.Trim()); var con = (Contact)(record["Contact"]); Console.WriteLine("{0},{1}", con.LastName.Trim(), con.Addresses.Count()); foreach (Address a in con.Addresses) { Console.WriteLine("....." + a.City); } Console.WriteLine(); }

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 117

Return to Table of Contents

The output of this example matches the output of query in Example 4-50.

4.8. Deferred Loading and Eager Loading queries So far all of the queries that involved returning related data have explicitly asked for that data in the query itself. Entity Framework will only return data that you explicitly ask for. If you're query only asks for contacts, Entity Framework will not make an assumption that just because Contacts have Addresses, it should bring you back the Addresses any time you query for Contacts.. Consider a typical model for sales information. A contact is related to a customer; a customer has sales orders; each sales order has line items; each line item relates to a product; each product comes from a vendor and is also related to a category. Can you imagine if you queried for contacts and without expecting it, the entire contents of the database were returned—because it was all related. It is possible to get related data after the fact. For example, if you queried for a selection of contacts, as you work with those contacts in code, you can request the contact's addresses without performing another complete query. This is referred to as Deferred Loading and although it does not require a new query to be constructed and executed, it does require the explicit step of calling a Load method.

4.8.1. Deferred Loading Entity Collections with Load The following LINQ to Entities query returns an ObjectQuery of Contact entities. VB From c In context.Contacts Select c C# From c in context.Contacts select c

Because the query does not explicitly request the Addresses, the Addresses.Count for every single contact will be 0. What you need to do is tell Entity Framework to go get the Addresses for the current Contact. VB For Each contact In contacts contact.Addresses.Load Console.WriteLine(contact.Addresses.Count) Next C# foreach (var contact in contacts) { contact.Addresses.Load(); Console.WriteLine(contact.Addresses.Count); }

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 118

Return to Table of Contents

When Load is called, Object Services will execute a query to retrieve all of the Addresses for that contact. In above example, after Load is called, the value of Count will be correct and the Address entities for that contact will all be available.

4.8.1.1. Performance Considerations with Deferred Loading There is a big performance consideration here. For each contact, the code is forcing an extra round trip to the database. If the query returns 40 contacts, then one more trip is made to the database for each contact when Load is called. That's 40 round trips to the server in addition to the original trip made to execute the first query. This can be extremely inefficient and might also get you in big trouble with the ITPros in your company. Load is a great choice in cases where you want to inspect the contact and only load addresses for particular contacts. Perhaps you want to list all contacts, but for contacts that were added after a particular date, you need to see how many addresses are in the database. The code in Example 4-53, demonstrates this. Example 4-53. Loading addresses for some of the contacts VB For Each contact In contacts Console.WriteLine(contact.LastName) If contact.AddDate > CDate("1/1/2008") Then contact.Addresses.Load() End If Next C# foreach (var contact in contacts) { Console.WriteLine(contact.LastName); if (contact.AddDate > System.Convert.ToDateTime("1/1/2008")) { contact.Addresses.Load(); } }

4.8.1.2. Loading the EntityReference You can also perform deferred loading for Entity Reference navigation properties, for example Address.Contact. However, rather than Load from the Contact property, you must load from the additional property that was created, ContactReference Entity Framework sees Address.Contact as merely a Contact entity and that does not have the Load method or capability. It is the ContactReference property that has the knowledge of how to load the related information. Each EntityRef Navigation property will have a related property with "Reference" appended to its name. As a reminder, the additional property is created when the classes are generated from the model. Example 4-54 shows loading ContactReference data for particular addresses after the addresses have already been queried.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 119

Return to Table of Contents

Example 4-54. Loading EntityReferences VB Dim addresses = From a In context.Addresses Select a For Each address In addresses If address.CountryRegion = "UK" Then address.ContactReference.Load() End If Next C# using (PEF context = new PEF()) { var addresses = from a in context.Addresses select a; foreach (var address in addresses) { if (address.CountryRegion == "UK") { address.ContactReference.Load(); } } }

4.8.2. Using the Include Method to Eager Load In cases where you know that you will need all of the Addresses up front, it may be more efficient to retrieve them as part of the original query. While you have seen how to do this with projection by including the Addresses in the SELECT clause, the Include method is another way to achieve this and may be preferable for a variety of reasons. Include is a Query Builder method and can be applied to ObjectQueries. Because context.Contacts is an ObjectQuery, you can use Include even within a LINQ query as in Example 4-55. Example 4-55. The Include method in a LINQ to Entities Query VB From c In context.Contacts.Include("Addresses") _ Where c.LastName = "Smith" _ Select c C# from c in context.Contacts.Include("Addresses") where c.LastName= "Smith" select c

The argument for Include,is a string which is the name (or names) of the Navigation Properties to bring back along with the Contacts. This is referred to as eager loading or eager fetching. Include can only be used when returning an ObjectQuery of a single entity type. It cannot be used with projections, and if you do project, Include will be ignored. Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 120

Return to Table of Contents

In the sample model, there is only one navigation property for con which is "Addresses". Imagine a sales model with a number of entities and variety of navigations. You could query customers and eager load the orders and all of the order's details by querying Customers.Include("Orders.OrderDetails"). The string is called a Query Path because it defines the path that the query should navigate through the model. Additionally you could eager load the orders and the customer's Addresses by chaining the Include methods like this: Customers.Include("Orders.OrderDetails").Include("Addresses").

4.8.2.1. How is the data shaped with Include? This is one of the interesting benefits of Include. What is returned from above query that queried Contacts.Include("Addresses") is a set of Contact entities. This does not have the same effect as projection which would have to return DbDataRecords. Figure 4-8 shows the query results in the debugger's QuickWatch window. You can see that the results are strictly a set of Contact entities. Where are the Addresses? Figure 4-8. The result of the Include (with no projections) returns only the primary entity of the query.

Figure 4-9, drills into one of the Contacts and you can see that both of this contact's Addresses are there. The Include brings in the related data and, unlike the issue you saw with the Addresses not being attached to Mr. Alderson from Montreal until all of the addresses had been enumerated through, these addresses are all present as soon as you get to the Contact. Figure 4-9. Figure Caption Text Goes Here

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 121

Return to Table of Contents

4.8.2.2. Accessing Properties from an Include in the Query You can filter, sort even when an Include is involved, though there is one caveat. The caveat is that you cannot limit which records are included. You will always get the entire EntityCollection referenced in the Include.

NOTE

Remember that if you do projection in your query, Include will be ignored. You can, however, use the properties of the Include entities in many of the same ways you can use properties of any related data when querying. Example 4-55 uses the CountryRegion field of Address to limit which Contacts are retrieved. But be sure you are clear on the results. This will return contacts that happen to have any of their addresses in the UK. If a contact has multiple addresses and only one of them is in the UK, you will still get all of those Addresses. Example 4-56. Example Caption Text Goes Here VB From c In context.Contacts.Include("Addresses") _ Where c.Addresses.Any(Function(a) a.CountryRegion = "UK") C# from c in context.Contacts.Include("Addresses") where c.Addresses.Any((a) => a.CountryRegion == "UK") select c

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 122

Return to Table of Contents

4.8.3. Include and Entity SQL ObjectQuery How would you apply Include when creating an ObjectQuery directly rather than using LINQ to Entities? Include is a QueryBuilder method and can be used in the same manner as other Query Builder methods. You can add it to CreateQuery methods or the ObjectQueries returned by CreateQuery. Example 4-57 shows how to apply Include when using CreateQuery. Example 4-57. The Include method in an Object Services query with Entity SQL VB Dim str = "SELECT VALUE c FROM PEF.Contacts as c " Dim contacts = context.CreateQuery(Of Contact)(str).Include("Addresses") C# var str = "SELECT VALUE c FROM PEF.Contacts as c "; var contacts = context.CreateQuery(str).Include("Addresses");

The same rule applies for projections when using Entity SQL with Include. If you project in your query, Include will be ignored. It is only able to work when there are complete entities involved. Pay attention to JOIN queries. If you use Include in a query that also has a Join, the Include will be discarded — no warnings, no compiler errors. Try a nested query instead but validate your results.

4.8.4. Loading Entity References So far you have seen loading, both deferred and eager, used with Entity Collections. It can also be done with Entity References – the "one" end of a Many to One or One to One relationship. In many cases this will be the parent of a parent/child relationship. Loading Entity References explicitly with the Load method is a bit different than loading the Entity Collection. The Addresses navigation property of a Contact is an EntityCollection of Address types and Load is a method of the EntityCollection class. The Contact property of an Address is an Contact object and there is no Load method for the Contact entity. For Navigation Properties that point to the "one" end of a relationship, Entity Framework's code generator creates two properties in the .NET class that represents the Entity. The first property is, in the case of Address, the Contact property which returns a Contact entity. The second property is a property which returns an EntityReference type. EntityReference is a generic class, so it will be of the same type as the navigation property.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 123

Return to Table of Contents

The Address.ContactReference is an EntityReference(Of Contact) or in C# EntityReference. It is this property that you need to use for the Load method when you want to explicitly load the Entity Reference. Example 4-58 shows Load being used to retrieve a Contact from the database and then, as proof that the Contact was loaded, the LastName is written out to the Console. Example 4-58. Using EntityReference.Load VB Dim addresses = From a In context.Addresses Select a For Each address In addresses If address.CountryRegion.Trim = "UK" Then address.ContactReference.Load() Console.WriteLine(address.Contact.LastName) End If Next C# var addresses = from a in context.Addresses select a; foreach (var address in addresses) { if (address.CountryRegion.Trim() == "UK") { address.ContactReference.Load(); Console.WriteLine(address.Contact.LastName); } }

When using the Include method to eager load EntityRefs, use the navigation property that property name (Contact), not the EntityReference property (ContactReference). VB Dim querystring = "SELECT VALUE add " & _ "FROM ProgrammingEFDB1Entities.Addresses as add" Dim addresses = PEF.CreateQuery( _ Of ProgrammingEFDB1Model.Address)(querystring).Include("Contact")

Just as you saw when using Include to load EntityCollections, an entity object will be returned, not an anonymous type, and the Entity Reference is loaded.

4.8.5. Pros and Cons of Load and Include There are definitely considerations to be made when choosing between these two methods. While the load may require additional round trips to the server, the Include method may result in a large amount of data being streamed back to the client application and then processed as the data is materialized into objects. This would be especially problematic if you are doing all of this work to retrieve related data that may never even be used. As with many choices in programming, this is a balancing act that is determined by your particular scenario.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 124

Return to Table of Contents

The documentation also warns that that using Query Paths with include could result in very complex queries at the data store because of the possible need to use numerous joins - the more complex the model, the more potential there is for trouble. You could certainly balance the pros and cons by combining the two methods. For example you can load the Customers and Orders with Include and then pull in the order details on an as needed basis with Load. The correct choice will most likely change on a case by case basis.

NOTE

There are a few methods for retrieving a single entity without even writing a query. They are called GetObjectbyKey and GetObjectStateEntry. These methods have counterparts called TryGetObjectbyKey and TryGetObjectStateEntry. The methods exist in another Entity Framework class and you will learn how to use them in Chapter 16, ObjectStateManager & MetadataWorkspace.

4.9. Retrieving a single entity All of the queries so far have returned sets of data. What if you wanted to retrieve a single entity or a single result. The queries return IQueryables or QueryObjects and you need to dig into those to get at the actual data which might be entities, anonymous types or DbDataRecords. This is reasonable if you are returning multiple items, but what about cases where you query for one particular item, for example the Contact whose ContactID=63 and you don't want to have a IQueryable returned, but just the item? LINQ to Entities has a pair of methods, First and FirstorDefault, which will return the first item in the result set. These methods are not specific to LINQ to Entities, but come from LINQ and may be familiar to you already. Example 4-58 shows to ways to use these methods. In the first, a query is defined and then in another line of code the First method is called. This will cause the query to be executed and the contact entity will be returned. The next d appends the First method directly to the query. Even though First is a method, you can combine it with the query operator syntax by wrapping the query in parentheses. In this case, the query is executed immediately and the contact is returned.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 125

Return to Table of Contents

Example 4-59. Querying with the First method VB Dim contacts = From c In context.Contacts Where c.ContactID = 63 Dim contact = contacts.First Console.WriteLine(contact.LastName) Dim singleContact = _ (From c In context.Contacts Where c.ContactID = 24 Select c).First Console.WriteLine(contact.LastName) C# var contacts = from c in context.Contacts where c.ContactID == 63 select c; var contact = contacts.FirstOrDefault(); Console.WriteLine(contact.LastName); var singleContact = (from c in context.Contacts where c.ContactID == 24 select c).First();

There's a potential problem here. If there are no items, First will throw an InvalidOperationException with the message "Sequence contains no elements". FirstorDefault protects you from the exception by returning the default, which is generally a null (Nothing in VB). In Example 4-58, FirstorDefault is used to avoid an exception being thrown. Contact in this case will be Nothing/null after the query is executed. Example 4-60. Using FirstorDefault to avoid an exception VB Dim contact = _ (From c In context.Contacts Where c.ContactID = 7654321).FirstOrDefault C# var contact = (from c in context.Contacts where c.ContactID == 7654321 select c).FirstOrDefault();

NOTE

If you were wondering about the Single and SingleOrDefault LINQ methods, these are not supported by LINQ to Entities.

4.10. Entity SQL's Wrapped & Unwrapped results There is one last concept to highlight before finishing up this chapter and moving on — understanding when Entity SQL queries will return rows containing values or just values. By default, queries using Entity SQL (ObjectQueries and EntityClient queries) return rows. The rows are contained in the resulting ObjectQuery or the EntityClient's DbDataReader. Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Return to Table of Contents

Page 126

When the data is pulled out of the row as part of the query process, this is referred to as "unwrapping". Then rather than a row, the ObjectQuery and DbDataReader will contain the returned value. You just saw the use of the First and FirstorDefault methods to return a single object rather than an IQueryable which would then need to be enumerated through to get at the object. Conceptually, Entity SQL queries that unwrap results are doing the same thing.. Unwrapping is only possible when a single value is returned in the ObjectQuery or DbDataReader. An EntitySQL query will return rows with the same number of columns as items listed in the projection, regardless of what type the item is – a string, an entity, even a collection. Take for example, a simple projection of names as shown in Table 4-1 or one that returns shaped data. Table 4-2 shows rows that each contains three strings and an EntityCollection. Each row in the results of 3 results contains an entity and an EntityCollection.

NOTE

The rows in the tables represent a DbDataRecord type.

Table 4-1. Table 4-1. Col 1 Mr. Sr. Mrs.

Row 1 Row 2 Row 3

Col2 John Pablo Olga

Col 3 Doe Rojas Kolnik

Table 4-2. Table 4-2.

Row 1

Col 1 Mr.

Col2 John

Col 3 Doe

Row 2

Sr.

Pablo

Rojas

Row 3

Mrs.

Olga

Kolnik

Col 4 Address Entity Address Entity Address Entity Address Entity Address Entity Address Entity

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Return to Table of Contents

Page 127

Table 4-3. Table 4-3.

Row 1

Col 1 Contact Entity

Row 2

Contact Entity

Row 3

Contact Entity

Col 2 Address Entity Address Entity Address Entity Address Entity Address Entity Address Entity

Because neither Object Services nor EntityClient can return anonymous types, the only way to return these multi-column rows is to wrap them in rows where the values are contained in columns. Once you have the result set in memory, you can extract the entities or values programmatically and interact with them as you have done in this chapter and the previous chapter. However, consider a query with only one value being returned in each row. By default, you will still get a DbDataRecord and that value will be the first and only column of the row.

Row 1 Row 2 Row 3

Col 1 Contact Entity Contact Entity Contact Entity

By adding the VALUE keyword (SELECT VALUE ...), that signals that you want the value to be unwrapped. With Object Services, this will result in an ObjectQuery of Contact entities. As you have seen, you must specify the proper type for the ObjectQuery. This could be one of the EntityObject types defined in your model, or some other type, such as a String or an Integer. Look at the difference in how you need to work with the results when the Contact is wrapped (Example 4-61) or unwrapped (Example 4-62). When it's wrapped you still need to cast the value in the first column (Item(0)) to a contact before you can work with the contact even though it's the only value in the result. Example 4-61. Wrapped Contact VB Dim esql = _ "SELECT c FROM PEF.Contacts as c WHERE c.FirstName='Robert'" Dim wrappedContacts = context.CreateQuery(Of DbDataRecord)(esql) For Each record In wrappedContacts Dim contact = CType(record.Item(0), Contact) Console.WriteLine(contact.LastName) Next C# var esql = "SELECT c FROM PEF.Contacts as c WHERE c.FirstName='Robert'"; var wrappedContacts = context.CreateQuery(esql);

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 128

Return to Table of Contents

foreach (var record in wrappedContacts) { var contact = (Contact)(record[0]); Console.WriteLine(contact.LastName); }

Example 4-62. Unwrapped Contact VB Dim esql = _ "SELECT VALUE c FROM PEF.Contacts as c WHERE c.FirstName='Robert'" Dim unwrappedContacts = context.CreateQuery(Of Contact)(esql) For Each contact In unwrappedContacts Console.WriteLine(contact.LastName) Next C# var esql = "SELECT VALUE c FROM PEF.Contacts as c WHERE c.FirstName='Robert'"; var unwrappedContacts = context.CreateQuery(esql); foreach (var contact in unwrappedContacts) { Console.WriteLine(contact.LastName); }

4.10.1. Entity SQL Rules for Wrapped and Unwrapped Results Here are some rules to remember for Entity SQL queries: • • • •

Use SELECT when projecting more than one value. When querying with SELECT, the ObjectQuery type must be a DbDataRecord. SELECT VALUE can be used when projecting a single value or entity. When querying with SELECT VALUE, the ObjectQuery type must be the same type as the value being returned.

Breaking any of these rules will result in a runtime exception when Entity Framework attempts to generate the store's SQL from the Entity SQL or when the data is returned an Entity Framework is trying to align the returned type with the type defined for the ObjectQuery.

4.10.2. Digging a little deeper into EntityClient's results Because Entity Client streams results and does not materialize records, you won't get entity Object. However, the resulting data will be shaped based on the entity shape and therefore, as you have seen in some of the earlier example, you can cast the results back to the appropriate entity. You can also cause the results to be wrapped or unwrapped. Remember that DbDataRecords can contain nested DbDataRecords or even nested DbDataReaders which is how it's possible to shape the results.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 129

Return to Table of Contents

Here is a variety of different queries and the results to expect in EntityClient. •

Query projecting two simple values: SELECT c.FirstName,c.LastName FROM PEF.Contacts AS c

Each row of the resulting DataReader is a DbDataRecord with two columns. Each column contains a string. •

Query projecting a single value. The value is an entity: SELECT VALUE c FROM PEF.Contacts AS c

Each row of the resulting DataReader is a DbDataRecord with one column. The column contains an IExtendedDataRecord which is a type of a DbDataRecord. There is one column for every property in a contact entity, filled with the relevant data. •

Complex Query projecting an entity and a collection of entities: SELECT

c, c.Addresses FROM PEF.Contacts AS c

Each row of the resulting DataReader is a DbDataRecord. There are two columns. The first column contains an IExtendedDataRecord with one column for each property of the Contact entity. The second column contains a whole DbDataReader that implements IExtendedDataRecord. This allows the data to be cast to an EntityCollection of Address types.. •

Query projecting a single entity using SELECT VALUE: SELECT VALUE c FROM PEF.Contacts AS c

Each row of the resulting DataReader is an IExtendedDataRecord. There is one column for every property of the Contact entity, filled with the relevant data. •

Query projecting a single simple type using SELECT VALUE: SELECT VALUE c.LastName FROM PEF.Contacts AS c

Each row of the resulting DataReader is a string.

NOTE

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 130

Return to Table of Contents

The ADO.NET documentation has a great example of reading a DbDataReader and handling any of these data types as you hit them. Look for the MSDN Library topic "How to: Execute an Entity SQL Query Using EntityCommand (Entity Framework)".

4.11. Summary With LINQ to Entities, Entity SQL, Object Services and EntityClient, Entity Framework provides myriad possibilities for querying data and shaping results.

Licensed by Dave Olsen

While it would take a few hundred more pages to ensure that you have seen an example of almost any type of query you may want to write, these last two chapters should leave you very prepared to venture forth. Beginning with the next chapter, you will start writing some solutions and be able to leverage many of these types of querying. You will start with a fresh database to make things a little more interesting and you may be happy to know that you won't be stuck with a very long default model and entity container name.

Chapter 5. Basics of Stored Procedures in the EDM Many databases use stored procedures to perform predefined logic on database tables. While one of the key features of the Entity Framework is its ability to automatically build native commands based on your LINQ to Entities or Entity SQL queries as well as the commands for inserting, updating or deleting data, you may want to override these steps and use your own pre-defined stored procedures. The sample database includes four stored procedures which we skipped over in the model creation in Chapter 2. In this chapter, you will update the model, pulling in those four stored procedures, implement them in the model and interact with them in some code. This chapter will focus on the stored procedure functionality that is readily supported by the EDM Designers. A later chapter will dig further into working with stored procedures that are not so easily implemented.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 131

Return to Table of Contents

5.1. Saving Entity Changes back to the database So far, we have focused on retrieving data from the database. Entity Framework also lets you easily save changes back to the database. You can insert new entities or update or delete entities that came from the database. There is a single method of the ObjectContext that orchestrates this — SaveChanges. While you will focus on modifying and saving data a little later in this book, it will be helpful to have some context before working with the stored procedures. As you interact with entities in your application, Entity Framework keeps track of the changes. Then when it's time to save changes back to the database, Object Services reads all of the change tracking information and constructs the appropriate commands to insert, update or delete data in the database. Each action is executed as a separate command. If you have created ten new entities, there will be ten insert commands individually executed on the database. What you will be doing in this chapter is overriding the Entity Framework's command generation a particular entity and directing it to use your stored procedures instead when SaveChanges is called.

5.2. Updating the model The EDM tools provide an Figure 5-1 feature which is available from the context menu of the designer. This can be used to add newly created database objects or even new items to existing objects. For example if a new table has been added to the database, Update Model will bring the table in to the model and create a new entity for it, just as the Create Model wizard did with other objects. Additionally, if you have added new columns to an existing table for which an entity exists in the model, those fields will come into the model and be added to the entity automatically. Not all changes will be surfaced in the conceptual model, however. For example, if you change the spelling of a column name in the database, the wizard will not know to line it up with the existing entity property and a new property will be created. In this case you would need to remove the new property and modify the entity mappings so that the existing property points to the correct column.

5.2.1. Add in the Stored Procedures Right click anywhere in the Model Browser and select Figure 5-1. A wizard will open instructing you to Choose Your Database Objects. Only the Stored Procedures node can be expanded because there are no tables or views in the database that aren't already in your model. This is not based on which entities you have created, but the fact that those

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 132

Return to Table of Contents

tables and views are represented in the SSDL portion of the model. Because you did not include the Stored Procedures when you first built the model, they are not represented in the SSDL and therefore seen as new.

NOTE

If new tables and views had been added to the database, you would see them listed here as well. The Stored Procedures will list procedures and User Defined Functions in the database.

NOTE

Note that for Version 1 of Entity Framework, Scalar User Defined Functions (UDFs) are supported, but Table-Valued UDFs will not be supported. This impacts how you will be able to query the Scalar UDFS and will be addressed in a later chapter. Checking Stored Procedures will automatically select all of the available procedures. You can expand the node to see what's there or to individually select the objects you want to use. For this example, you'll want all four: CustomersbyState, DeleteContact, InsertContact and UpdateContact. Figure 5-1. Update Model from Database will display the Update Wizard where you can select database objects that aren't already contained in your model.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 133

Return to Table of Contents

There are two other tabs in the wizard. These will display which existing items in the model will be refreshed and if any of the database items have been deleted, which items will be deleted from the model. These two tabs are read-only. Click Finish to get the stored procedures added to the model.

5.2.2. Update Model's impact on the model When the update is complete, the model will not look any different in the designer. Stored Procedures do not automatically get surfaced to the Conceptual layer of the model. Instead, they have been represented in the SSDL as Function elements. It will be your job to define how these functions should be implemented in the Conceptual layer.

5.3. The New Functions in the Model Functions represent Stored Procedures and User Defined Functions that are in the database. Example 5-1 lists the four functions that were created in the SSDL. Example 5-1. Functions listed in the SSDL

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 134

Return to Table of Contents



Each of these four functions represents a different Stored Procedure in the database. The first, CustomersbyState represents the following T-SQL query: PROCEDURE [dbo].[CustomersbyState] @statecode nchar(50) AS SELECT DISTINCT contact.* from [Contact],[Address] WHERE [Contact].[ContactID]=[Address].[contactID] AND [Address].[StateProvince]=@statecode

The Insert, Update and Delete procedures perform the relevant changes to the database.

5.3.1. Function Attributes Most of the function attributes align with attributes that are common to database procedures. Because the SSDL is describing the data store, these attributes are applied in the model so that the Entity Framework API will have a thorough description of the procedure. Aggregate, BuiltIn and NiladicFunction are all attributes that apply to User Defined Functions, not Stored Procedures. For Stored Procedures they will always be false. Because these are optional and false by default, they are not even required here. If you were adding Functions in manually for Stored Procedures, you wouldn't even need to use these, but the wizard inserts them.

NOTE

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 135

Return to Table of Contents

What the heck does Niladic mean anyway? Niladic is a mathematical term meaning that the function takes no input parameters. SQL Server's GetDate() is an example of a niladic function. IsComposable refers to whether or not the results of the function can be used in another query. This must always be false for Stored Procedures. ParameterTypeSemantics attribute refers to the input parameter, statecode. The AllowImplicitConversion enum (which is the default) merely means that the data type input can be converted implicitly to a store provider data type if necessary. For example if an integer is passed into this parameter, EF will just go ahead and convert it to a char when creating the command to execute the Stored Procedure. The Parameter element describes any input or output parameters. In this case, there is only an input parameter, specified by Mode="In". Mode options are "In", "InOut", "Out" and "ReturnValue". These align with the stored procedures flags to define parameters that are being sent to the procedure. In In parameters are read by the stored procedure Out Out parameters are populated by the procedure and returned InOut InOut parameters are read by the stored procedure and returned. The procedure may or may not update this parameter before returning it ReturnValue The stored procedure may create a value and return that as the last operation in the procedure. This will be captured by Entity Framework. An example of this is after an Insert, the stored procedure might return a newly generated identity value. You'll notice that the parameter in the SSDL is nchar, where the parameter in the database's procedure is more explicit: nchar(50). This won't pose a problem when the data is sent to the Stored Procedure thanks to the AllowImplicitConversion enum. The other enumerations are explained in the documentation. Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 136

Return to Table of Contents

NOTE

Notice that for this query function, the SSDL only defines what is necessary to call the function. There is no indication of returned data. You'll see more about how Stored Procedures are implemented from the SSDL back to the CSDL later in this chapter. Now take a look at a more complex function, UpdateContact. Here is the actual stored procedure. PROCEDURE UpdateContact @contactid INT, @firstname NCHAR(50), @lastname NCHAR(50), @title NCHAR(50) AS UPDATE Contact SET [FirstName]=@firstname,[LastName]=@lastname,[Title]=@title, [ModifiedDate]=GETDATE() WHERE [ContactID]=@contactid

The UpdateContact function in the SSDL has the same attributes as the CustomersbyState function as well as parameter elements to represent the input parameters. You will see later in this chapter how mappings are used to easily leverage the Update, Insert and Delete stored procedures when coding against the EDM. You'll also see how the query Stored Procedure (CustomersbyState) is handled differently than the DML functions.

DML, CRUD and CUD DML is a frequently used acronym for Database Manipulation Language and refers to the three types of functions that manipulate data – Insert, Update and Delete. You will also frequently see the term CRUD used which encompasses these three as well as Reads. CRUD stands for Create, Read, Update and Delete (where "Create" is used rather than "Insert" since CRUD sounds much better than IRUD). Lastly, some people use the term CUD to refer to the same three DML operations (Create, Update, Delete). Unfortunately, CUD has a different meaning for people who live in cow country, so we trend towards DML instead.

5.4. Implementing the Functions In Chapter 5, you will begin modifying objects and saving them back to the database. As you will see, the default behavior when you save entities in Entity Framework is that the

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 137

Return to Table of Contents

API constructs the necessary Insert, Update and Delete commands on the fly to save changes to the database. You can override this behavior for specific entities by using the functions instead. You can map functions to one entity, but not to others. EF will figure out which ones will use functions and which ones need to have the commands generated when it comes time to SaveChanges. The CustomersbyState stored procedure is for reading data, not updating. You can link functions for "read" stored procedures to entities that match what is returned by the procedure. There are other ways to use these functions in the Entity Data Model but the designer only supports these two scenarios which are what will be covered in this chapter. A later chapter will dig into working with stored procedures that are not quite as simple to implement.

NOTE

You will find the terms Stored Procedures and Function used throughout the model and the designer. The model consistently refers to functions, while the designer, in an effort to use familiar terminology, uses Stored Procedures in a number of places.

5.4.1. Rules for Mapping Functions to Entities There are some strict rules for mapping functions.

5.4.1.1. All or Nothing You must either map all three functions or none of them. This is just how EF works with these mappings. Visual Studio will display an error (Error 2025) that says "the schema validation failed for mapping schema". The error details explain that the mapping is incomplete and will even tell you which of the three function mappings is missing.

5.4.1.2. No Random Input or Output Parameters Every input parameter of a function must line up with a property in the entity. You can't substitute your own data to use as an input parameter. It can only be one of the entity's properties.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 138

Return to Table of Contents

5.4.1.3. Associations to EntityReferences require input parameters on all three functions This is a rule that we won't focus on in this example. However if you were mapping functions to the Address, there are some special considerations that need to be made with respect to the Contact navigation property. You'll work out this scenario in a later chapter.

5.4.2. Wiring up Insert, Update and Delete Functions to an Entity By default, the Entity Framework generates dynamic SQL when it is asked to save changes back to the database. It is possible to override that behavior by identifying your own Insert, Update and Delete functions. This takes advantage of the work done by DBAs to ensure that their own rules and regulations can be followed. If you look more closely at the Mapping Details window, you will notice two icons in the upper left corner. Select the Contact entity in the designer to display its Mappings. The icons will become active and the top one is selected. Clicking the top icon causes the Mapping Details to display the table mappings. The lower icon is to display function mappings. You can also display function mappings by right clicking on an entity and choosing Stored Procedure Mappings. In the Details window, you will see three place holders to select an Insert function, an Update function and a Delete function as shown in Figure 5-2. Figure 5-2. The Function or Stored Procedures view of the Mapping Details window

Click on the first item, "Select Insert Function", which will display a drop-down list arrow to the right. Click the arrow to see the options. The designer will identify all of the unmapped functions in the store layer and present them in the drop-down list. Select the "InsertContact" function. The designer will discover the parameters that are defined in the SSDL and automatically map them to properties in the Contact entity which have matching names. In the case of this example, everything lines up perfectly as you can see in Figure 5-3.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 139

Return to Table of Contents

Figure 5-3. The InsertContact function has been mapped to the Contact Entity.

You'll also notice under the Parameters is a "Result Column Bindings" item. The InsertContact stored procedure happens to return the new ContactID that was generated when the contact is inserted. PROCEDURE [dbo].[InsertContact] @firstname NCHAR(50), @lastname NCHAR(50), @title NCHAR(50) AS INSERT INTO [Contact] ([FirstName] ,[LastName] ,[Title] ,[AddDate] ,[ModifiedDate]) VALUES (@firstname,@lastname,@title,GETDATE(),GETDATE()) SELECT SCOPE_IDENTITY() AS NewContactID WHERE @@ROWCOUNT > 0

You can map that resulting NewContactID value directly to the Entity's ContactID property. That will mean it will not be necessary to re-query the database to acquire the ContactID for an inserted Contact. You'll see more about this in a later chapter when you interact with the database. For now finish up the Insert function mapping by typing NewContactID over the text . The ContactID will be automatically chosen as the property to map to because it is the EntityKey for Contact and therefore a very good first guess for the Designer to make for you. Select the DeleteContact and UpdateContact functions to map to the other two functions. There are no other return values so you will not need to apply a ResultColumnBinding for the Update. Figure 5-4. After you have completed mapping the Stored Procedure functions, the function mappings for Contact should look like this.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 140

Return to Table of Contents

5.4.2.1. The Use Original Value option There is one last point to be made about the Mapping Details for functions and that is the Use Original Value checkbox for the Update function. You will learn in a later chapter about change tracking in the Entity Framework. An entity will have an original value and a current value. If the entity has been modified, the current value will be used for the update by default. Here you have the ability to modify that behavior.

5.4.3. Inspect the Mappings in the XML Now it's time to see how these mappings have impacted the MSL section of the model in the raw XML. Within the EntitySetMapping section for the Contacts EntitySet, a second Section 2.11.1.3.1 section has been added. The first is the one that defines the scalar property mappings for Contact. The new EntityTypeMapping contains an inner element called ModificationFunctionMappings. Within this element the three functions are mapped out. Example 5-2. EntitySetMapping with Function Mappings added in

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 141

Return to Table of Contents



In you can see that a second EntityTypeMapping element has been added to the Contacts EntitySetMapping. Within this new section, each of the functions are listed and based on all that you have learned about reading this file already, the elements should be familiar and the mappings should be logical. Notice in the UpdateContact, each ScalarProperty has a Version attribute. That is the notation that ties back to the "Use Original Version" checkboxes which are unchecked and therefore the version is Current.

5.4.4. Using these Mapped Functions Now that the functions have been mapped to the entities, Entity Framework will automatically use them any time you call SaveChanges and there are Contact entities involved in the save. That's all there is to it. You won't call these functions directly in your code. To see this in action, you'll need to watch the SQL Server Profiler to see when the Stored Procedures are called rather than a generated command. Example 5-3 shows a test which retrieve an Address and a Contact, then edit both. You'll need to Example 5-3. Testing the Function Mapping VB Private Sub TestFunctionOverride() Using context As New PEF

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 142

Return to Table of Contents

Dim contact = context.Contacts.Include("Addresses") _ .Where(Function(c) c.Addresses.Any).First 'make a change to contact contact.LastName = contact.LastName.Trim & "-Jones" 'make a change to the address Dim address = contact.Addresses.First address.Street2 = "Apartment 42" 'call SaveChanges context.SaveChanges() End Using End Sub C# private static void TestFunctionOverride() { using (PEF context = new PEF()) { var contact = context.Contacts.Include("Addresses") .Where(c => c.Addresses.Any()).First(); //make a change to contact contact.LastName = contact.LastName.Trim() + "-Jones"; //make a change to the address var address = contact.Addresses.First(); address.Street2 = "Apartment 42"; //call SaveChanges context.SaveChanges(); } }

When the SaveChanges method is called, the required updates are sent to the database. Because you mapped the functions to the Contact entity, the change to this contact object is manifested in this command which executes the UpdateContact stored proceudure. exec [dbo].[UpdateContact] @contactid=325,@firstname=N'Virginia', @lastname=N'Miller-Jones',@title=N'Ms.

The Address entity has no mapped functions mapped; therefore Object Services constructed this Update command which was sent to the database. exec sp_executesql N'update [dbo].[Address] set [Street2] = @0 where ([addressID] = @1)', N'@0 nchar(12),@1 int', @0=N'Apartment 42',@1=2260

The second line of the command is the update command. The third line defines the parameters for the command and finally the last line passes in the parameter values. 'Apartment 42' is the new value of Street2 and 2260 is the AddressID of the Address to update. You will learn a lot more about how Entity Framework performs saves and how you can impact them as you move through the book. For now, let's continue to focus on the stored procedures.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 143

Return to Table of Contents

5.5. What about the READ Stored Procedure? So far we have dealt only with the Insert, Update and Delete functions. There is still another stored procedure that came into the model – the CustomersbyState procedure which does a query of the database and returns a set of rows from the Customer table. In our current model, a row from the customer table maps back exactly to the Customer entity which means that this procedure passes an important rule for wiring up read procedures in the EDM. The rule is that the results from the procedure must match an existing entity. Because CustomersbyState returns what equates to a Customer entity, it is easy to map this function using the tools.

NOTE

In a later chapter, you will learn how to wire up procedures that return results that do not match up to an entity The CustomersbyState procedure can be mapped using the Model Browser, not the Mapping Details. The next section deals with the Model Browser; this is where will learn to handle the CustomersbyState function as well as other features provided by the Model Browser.

5.6. The EDM Designer's Model Browser Right click in the background of the model in the Designer then select Model Browser from the resulting context menu. Figure 5-5. Viewing the CSDL and SSDL in the Model Browser

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 144

Return to Table of Contents

In Figure 5-5, a number of the model's objects have been expanded. This view of the model gives you a great way to see the overall picture of the Conceptual layer and the Store Layer without all of the nitty gritty XML. The Model Browser helps you navigate the objects in the Conceptual layer (entities, properties, associations). The lower portion allows you to navigate the items in the SSDL. Notice that in the model browser, these are referred to as Tables, Views and Stored Procedures and not their SSDL schema names, Entity, Function, etc. Many of the functions of the designer window are available in the context menu of the Model Browser as well, such as validating the model or view mappings or updating the model from the database.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 145

Return to Table of Contents

The Model Browse also it provides a means for mapping the functions from the SSDL. While some of these can also be mapped from an entities mapping details window, functions that are for reading data from the store can only be mapped from the Model Browser.

5.7. Map the last of the four functions — CustomersbyState. Right click the CustomersbyState Stored Procedure in the Model Browser and choose Create Function Import from the menu. The Add Function Import dialog will let you name the Function Import and map it to an existing entity or a scalar type (e.g. an Integer, String etc.). Figure 5-6. In the Add Function Import dialog you can map a stored procedure to either a Scalar type or an Entity. This procedure will return a Contact entity.

The new Function Import will not be displayed in the model in the designer, but you can see it in the Model Browser if you open up the first node, then drill into EntityContainer, then Function Imports. In the XML, you will find the following additions to the CSDL section inside the EntityContainer element.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 146

Return to Table of Contents

Notice that the return type is not a single Contact, but a collection of Contacts. If only one contact is returned, then you will end up with a collection with a single item. The mapping information is in a new FunctionImportMapping element in the MSL's EntityContainerMapping section. Unlike the Update, Insert and Delete mappings, this is not included as part of the Contact's EntitySet mappings, but it stands alone.

5.7.1. Using the CustomersbyState function After mapping the function, a new method is automatically generated for the ProgrammingEFDB1Entities class — CustomersbyState. You can call the method directly in your code using an instantiated context. VB Dim results = context.CustomersbyState("WA") C# var results= context.CustomersbyState("WA");

This is not the same as creating and executing a query. The function will be executed immediately when that line of code is hit. The return type will be a System.Data.Objects.ObjectResult(Of Contact) (in C#, an ObjectResult), which can be enumerated through or bound to data controls. You could also use one of the LINQ conversion methods to return a more common type of IEnumerable. For example, you could return a List of Contact objects rather than the ObjectResult using this code. context.CustomersbyState("WA").ToList()

5.7.2. Using Functions in a Query Because the function returns an IEnumerable (the ObjectResult) it is possible to use the function in a query. VB Dim results = From c In context.CustomersbyState("WA") Where c.LastName.StartsWith("S") C# var results = from c in context.CustomersbyState("WA") where c.LastName.StartsWith("S") select c;

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 147

Return to Table of Contents

However this is not a LINQ to Entities query, but an object query. What's the difference? The query will be performed on the results of the function. That means the function will be executed on the server side and then the results will be processed further in memory. If there are 800 customers in WA but only 3 of them have last name's that begin with S, all 800 customers will be returned from the database and then LINQ will pull out the three that you were really looking for. Databases do not support using Stored Procedures as sub-queries, which is why it is not possible to compose a LINQ to Entities query using these functions. Therefore .NET and EF coordinate to break the query up into which part is LINQ to Entities and which part is LINQ to Objects.

Licensed by Dave Olsen

5.8. Chapter Summary

Many developers and DBAs rely on Stored Procedures for a variety of reasons including consistency, security and reliability. Even though Entity Framework composes queries and commands automatically, you can override this default behavior by implementing your stored procedures in the model. This chapter showed the functionality that is readily supported by the designer which is mapping procedures to entities when the procedure's input parameters and results line up with existing entities and their properties. Chapter 13, Stored Procedures: Beyond the Basics, will dig further into these implementations as well as those which are a little trickier to pull off.

Chapter 6. Tuning up the Model In the previous chapters, you have focused on learning some of the core concepts of the Entity Framework, the EDM and querying. The last two of these chapters focused on a simplistic database and a console application in order to avoid distracting you from the lessons. Now it's time to look at some more realistic scenarios. This chapter will focus on creating a more realistic model. The model will be contained in its own assembly so that it can be reused in other applications in your enterprise. The chapter will also address two other important lessons – cleaning up a model that has been created from a database and handling model validation errors.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 148

Return to Table of Contents

6.1. The BreakAway Geek Adventures Business Model The company that you will be writing software for is BreakAway Geek Adventures. BreakAway Geek Adventures is a small company that arranges adventure vacations for hard working programmers who definitely need a break. The company can hook you up with vacations such as white water rafting in Belize or bicycling in Ireland. They have been in business for a number of years and have an old application that uses a SQL Server database for its data store. Now it's time to write shiny new applications in .NET leveraging the Entity Framework.

NOTE

You can download a copy of this database from the book website. Look for the database named BreakAway. There is a version for SQL Server 2005 and a version for SQL Server 2008. Here is the database schema. Figure 6-1. The BreakAway database schema

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 149

Return to Table of Contents

6.2. Create a Class Library Project to host an Entity Data Model Rather than create the EDM directly in the Windows application, in this chapter you will create a separate project for the EDM. This is a good start on the way to planning for larger applications. 1. In Visual Studio, create a new Class Library project named BreakAwayModel. 2. Delete the Class1 file that was automatically created. 3. Add a new ADO.NET Entity Data Model to the project. Change the default name (Model1.edmx) to BAModel.edmx. 4. On the Choose Model Contents page, choose Generate from Database, then select the BreakAway Data Connection if it has already been added to Visual Studio. If not, create it on the fly using the New Connection button. Leave the default connection settings name, BreakAway, alone for now and go to the next page of the wizard. 5. On the Choose Your Database Objects page, check all of the objects, Tables, Stored Procedures and View. Open up the Tables node. You will see that because the database contains a diagram, the table that controls the diagram is listed (sysdiagrams). Uncheck that since you Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 150

Return to Table of Contents

don't need the diagram in your model. Creating the diagram in SQL Server Management Studio also resulted in seven stored procedures and one function being added for the sake of diagramming. Their names all begin with either fn_ or sp_ and contain the word "diagram". They won't interfere with your model, but you can uncheck these procedures and functions if you prefer. 6. Leave the default Model Namespace intact. You'll get a chance to change that shortly, because there's another way that it will be useful to be aware of. 7. Wrap up the model creation by clicking the Finish button. The newly created model will open up in the designer window and should look something like Figure 6-2.

Why are the Database Diagram objects showing up in the EDM WIZARD? The Entity Data Model Wizard reads all of the objects whose owner is or ties back to dbo. In databases where different schemas are used, such as AdventureWorks, which has schemas for Person, Sales, HumanResources and more, those schemas are still owned by dbo and therefore tables like Sales.Customer are discovered by the wizard. Only users whose database login is in the db_owner role can create a Database Diagram, therefore the table created to house the metadata for the diagram as well as its related view and stored procedures are dbo objects and will show up in the list of objects available for modeling. Unfortunately, outside of deleting the model from the database, there's not much you can do about this.

Figure 6-2. The initial model created from the BreakAway database.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 151

Return to Table of Contents

6.3. Inspect and clean up the new model The first thing you should always do with a newly generated model is make sure that the names of the Entities and EntitySets make sense. The Entities should each be singular name (Contact, Address, Customer, etc.) and the EntitySet names should be the plural form of the Entity name (Contacts, Addresses, Customers, etc.). Equipment poses a challenge since the singular and plural version are the same. The designer appends the word "Set" to entities created in the designer, so we'll use EquipmentSet in this model. Although you can edit the Entity names right in the designer, you can only edit the EntitySet names in the Properties window. You may find it more efficient to edit both in the Properties window.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 152

Return to Table of Contents

NOTE

There are three ways to get an Entity's properties to display in the Properties window. 1) Select the entity in the designer, 2) select the entity in the Model Browser and 3) select the entity by from the drop down list of objects in the properties window.

6.3.1. Change Events to Trip and Locations to Destination The database has a table named Events. The original name of this table was a bad choice. Events refers to the trips that BreakAway schedules. With the Entity Data Model, you can rename the entity without having to rename the database table. As you fix up the names of the Entities and EntitySets, rename the Events entity to Trip. It will still map back to the Events table so everything will stay in synch. To match the entity, change the EventID property name to TripID. As you are working with objects, you won't have the confusion of an entity whose ID property doesn't match the name of the entity. Do the same for the entity named Locations, changing it to Destination. You'll need to change the ID and Name properties as well to DestinationID and DestinationName.

6.3.2. Collisions between property names and entity names There are two entities that will pop up an error message when you try to change their names. The first is CustomerTypes and second is Activities. The problem is that the entities contain properties with the same name that you would like the entity to have. Before you can change the CustomerTypes entity name to CustomerType, you will need to rename its CustomerType property. Change the name to CustomerTypeName. Then change the Activity property of the Activites entity to ActivityName. You can make this change in the designer or the Property window. You may also notice that the Equipment entity has a property called Equipment1. That is because the wizard saw that the property name matched the Entity name and therefore appended the "1" to the Property. Change that property to EquipmentName. Now you will be able to change the names of the entities without problems. Table 6-1 shows the resulting names. If you make these same changes, then the queries and other code that follow will work properly. Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 153

Return to Table of Contents

Table 6-1. Table 6-1. Entity Activity *Change the Activity property to ActivityName Address Contact Customer CustomerType *Change the CustomerType property to CustomerTypeName Equipment *Change the Equipment1 property to EquipmentName Trip (was Events) Destination (was Locations) Lodging Payment Reservation vOfficeAddress

EntitySet Activities Addresses Contacts Customers CustomerTypes EquipmentSet Trips (was Events) Destinations Lodgings Payments Reservations vOfficeAddresses

You'll notice some bad behavior by the designer as you rename some of the entities. When renaming the EntitySets, all is well, but when you rename the Entity, the designer will automatically rename the EntitySet using its pattern for new entities, which is to append the word Set onto the end. This means that after changing the Entity names, you'll need to re-edit the EntitySet names. Thankfully in this model, there are only eight entities that this will happen with. See the sidebar, Entity Naming in the Model, for some suggestions

6.4. Cleaning up the Navigation Property Names There is still a bit of cleaning up to do. Next you will fix up the names of the Navigation Properties so that they make sense when you are building queries and working with the objects returned from those queries. Navigation Property names should be plural when pointing to a Collection (e.g. Reservations that a Customer has made) and singular when pointing to a Reference (the Customer who made a Reservation). There are some odd navigation properties in the Customer Entity – Locations & Locations1 and Activities & Activites1. The Activity and Location entities each have Customers and Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Return to Table of Contents

Page 154

Customers1 in the Activity entity and the Destination entity. Fix up the other Navigation Properties as shown in Table 6-2, and then we'll come back to these. Table 6-2. Table 6-2. Entity Contact

Customer Trip Activity Destination Lodging

Payment Reservation

Original Nav Prop Name Address Customers Lodging CustomerTypes Destinations

Fixed Nav Prop Name Addresses Customer Lodgings CustomerType Destination

Events Lodging Events Destinations

Trips Lodgings Trips Destination

Events Reservations Customers Events

Trips Reservation Customer Trip

Reason 1:* Navigation 1:1 Navigation 1:* Navigation *:1 Navigation *:1 Navigation & Entity Name Changed Entity Name changed 1:* Navigation Entity Name changed *:1 Navigation & Entity Name changed Entity Name changed *:1 Navigation *:1 Navigation *:1 Navigation & Entity Name changed

As you write queries against this model going forward, the queries will be more logical. Rather than code against Reservation.Customers, when there will always be just one Customer, you will be able to use Reservation.Customer.

6.4.1. Entities with multiple relationships to a single entity Now we can go back to work on the Customer entity. It has those two funny pairs of Navigation Properties – Activities/Activities1 and Locations/Locations1. They will make more sense if you check the Customer table in the database, shown in Figure 6-3. Breakaway keeps track of each Customer's first and second preferences for Destination and Activity. Figure 6-3. The Customer table in the database has two columns that relate to the Destination table (PrimaryDesintation (sic) and SecondaryDestination) and two columns that point to the Activities table.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 155

Return to Table of Contents

The navigation property names however are derived simply from the name of the table on the other end of the relationship. Since there are two associations to one entity, the wizard appended "1" to the second navigation property.

6.4.2. Determining which Navigation Property is mapped to which Foreign Key field Before you can rename these Navigation properties, you'll need to figure out which foreign key fields the Navigation Properties belong too. For example, does Customer.Activities refer to the PrimaryActivity or the SecondaryActivity? You can do this by looking at the properties of each Navigation Property and seeing which Association it is bound to then looking at that Association and seeing which field is involved. Let's start with Activities. Click the Activities Navigation Property in the Customer entity. In its Properties window, the Association property is BreakAway. FK_Customers_Activities. Use the Properties window drop down (near the top of the Properties window) to select that Association.

NOTE

Note: Sometimes it's a little tricky to identify an association in the model. There are a number of ways to select an association in the model. The Properties window drop down is one way to select the association. You can also select it in the Model Browser. An additional method is to right-click a navigation property and choose "Select Association" from its context menu. Any of these methods will cause the

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 156

Return to Table of Contents

association to get highlighted in the designer and its properties to display in the Properties window. Right click the association's line in the model and select "Table Mapping" from the context menu. Table Mapping seems to be used generically in the designer. Now you can see that this Association is for the PrimaryActivity. Figure 6-4. Check the mapping details of an association in order to discover which Foreign Key is involved in the association

Rename the Activities Navigation Property to "PrimaryActivity" then rename the Activities1 Navigation Property to "SecondaryActivity". You can do the same detective work for the Locations and Locations1 Navigation Properties to see which one should be named PrimaryDestination and SecondaryDestination.

NOTE

Did you notice that the PrimaryDestination column was misspelled in the database? In the previous application, the developer had to constantly tangle with this field name. But with the Entity Data Model it will no longer be a problem. The other ends of these associations need to be fixed as well. The Activity entity has two navigations back to the customer entity. Going in this direction, the navigations represent "Customers who have listed this activity as their primary activity" and "Customers who have listed this activity as their secondary activity". Rename Customers to "PrimaryPrefCustomers" and Customers1 to "SecondaryPrefCustomers". Make the same changes to the Customers and Customers1 navigation properties in the Destination entity.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 157

Return to Table of Contents

6.5. Mapping a few Stored Procedures The database has a number of Stored Procedures. For now we'll do function mapping for the procedures for the Payments table, InsertPayment, UpdatePayment and DeletePayment, using the same technique that you learned in Chapter 5. Open the Stored Procedures Mappings window for the Payment entity and select the appropriate functions for Insert, Update and Delete.

6.5.1. Map the Insert function The InsertPayment function returns a newly generated PaymentID called NewPaymentID. The parameter names don't match the property names of the entity; therefore you will need to manually map some of the properties. Notice that the InsertPayment function needs to know the ReservationID. In the model, Reservation is a Navigation Property of the Payment Entity. You will have access to the Navigation Property in the mapping window so you can select Reservation.ReservationID to map to the required parameter. Be sure to map that to the Result Column Bindings as you did for the InsertContact function in the previous chapter. The Insert mapping should look the same as in Figure 6-5. Figure 6-5. Map the input parameters and the results of the InsertPayment stored procedure to properties in the Payment entity.

6.5.2. Mapping the Update Function When mapping the UpdatePayment function, you will also have to manually map the properties whose names don't match the input parameters.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 158

Return to Table of Contents

6.5.2.1. Use Original Values checkbox Because of the way that this stored procedure works, you can take advantage of the special "Use Original Value" column that exists only for the Update functions. The stored procedure performs a concurrency check against the timestamp field. If anyone edited the record in between the time that the user retrieved the record and attempted to save changes, the order won't get updated and a OptimisticConcurrencyException will be thrown. You'll learn more about working with Concurrency in Chapter 13. When a payment is updated, the database will automatically update the timestamp field. The UpdatePayment procedure returns the new timestamp value. Map that return value as shown in Figure 6-6. Figure 6-6. The UpdatePayment function mapping

6.5.2.2. The DeleteFunction mapping and an awkward Stored Procedure parameter A typical stored procedure for deleting a record takes the primaryKey field as a parameter. When you map the Delete function you will see that the DeletePayment function not only has the PaymentID as a parameter, but also ReservationID. This is in the database in advance to simplify your task of mapping the functions but you will not typically have the additional parameter. Why is it there and why should it make the mapping simpler? There is a mapping requirement with Entity Framework that makes it necessary. In the Insert and Update stored procedures, it makes sense to have the ReservationID as a parameter because that supplies the ForeignKey value that the Payment record in the database needs.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 159

Return to Table of Contents

As a general rule, Entity Framework requires properties that are involved in association mappings to be mapped in all of the function mappings for the entity. Because Payment has an association to Reservation, even in the function where it seems illogical, Delete, you must map the property that the association revolves around (Reservation.ReservationID). This is not meant to aggravate you or your DBA but it is how Entity Frameowrk is able to generically deal with all of the potential things you may try to achieve in your models and your queries. So unfortunately developers are stuck with the rule whether or not it makes sense to them. Putting the extra parameter(s) into the stored procedure in the database is the easiest way to deal with this. If that's not an option in your application, the alternative is to modify the SSDL of your model. You will learn in the Modelling chapter that it's possible to modify the SSDL to create virtual tables, stored procedures and functions that don't physically exist in the database. The downside to modifying the SSDL manually is that if you update the model, the SSDL and any modifications will be overwritten. At this stage in the book, it is simpler to just have the parameter written directly into the Stored Procedure. Map the DeletePayment function so that it matches Figure 6-7. Figure 6-7. The DeletePayment function mapping

Congratulations! You have just made quite a nice model from a highly normalized database. Since you have already done so much work on this model, performing more advanced customizations will be left to a later chapter. The current view of the model, with some of the entities moved around to make it more visually appealing, is shown in Figure 6-8. Figure 6-8. The new BreakAway model

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 160

Return to Table of Contents

6.6. Many-to-Many Relationships There is one more thing to point out about this model — the two many-to-many relationships. BreakAway Adventures' database keeps track of which type of Equipment is needed for which Activities. It also tracks which activities will be available on which events ("trips" in the model). To accomplish this, there is a join table between Equipment and Activities and a join table between Activities and Events as shown in Figure 6-9. Figure 6-9. The database join table, EventActivities, defines many-to-many relationships between Events and Activities. ActivityEquipment defines many-to-many relationships between Activities and Equipment.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 161

Return to Table of Contents

These tables did not surface in the model as entities. The EDM has the ability to represent many to many relationships while hiding the join in the mappings. But it can only do this when the join table has only the relevant keys and no extraneous fields. These two tables meet that criterion as they only have the IDs of the items they are joining. If there were additional properties in the join tables, such as DateCreated, then the EDM would have created entities for them. Instead, the joins are controlled in mappings; in the conceptual layer the relationships are expressed as navigation properties. Example 6-1 shows the mapping for the EventActivities Association in the XML file. The mapping identifies the EventActivities table as the target of the mapping, then shows its ActivityID field wired up to the ActivityID field. Its EventID field is wired up to the EventID field of the Events table. Example 6-1. Many-to-Many Association Mapping

As you can see in Figure 6-10, Activity and Equipment are joined in a many to many relationship. Thanks to the original table names, the Navigation Property names happen Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 162

Return to Table of Contents

to be just right and don't need editing. Each piece of Equipment has Activities and each Activity has a collection of Equipment. Each Activity also has Trips and every trip has a collection of Activities. It will be very convenient not to have to construct joins when traversing these relationships in queries. Figure 6-10. Because the join tables contain only the keys involved, the Entity Data Model can easily represent the relationship without the aid of a join entity.

With this mapping in place, not only does it enable the convenient association directly between the two entities, but querying, inserts and updates across this join are all managed by the mapping. You'll see this in action as you move through the book.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 163

Return to Table of Contents

6.7. Building the BreakAwayModel Project This will be enough for the model for now. Later you will incorporate other objects from the database. Now it's time to build the model into an assembly that you will be able to use in the many projects that you will be building in upcoming chapters.

6.7.1. Some more convenient names Before compiling the model, there are a few names that you will want to change so that when you access the model and its classes from another project, you won't have to work with cumbersome names.

6.7.1.1. BAGA Assembly Namespace You will have to make references to the assembly namespace throughout the code of your other applications which are using it. It will be handy to have a nice short name. The acronym for BreakAway Geek Adventures is BAGA, which is a good option. Open the project's Properties window and on the first page, Application, change the Root Namespace to BAGA.

6.7.1.2. Entity Container Name When you created the model with the EDM Wizard, you left the default name for the EntityContainer, BreakAway. Change that name to BAEntities. Remember that the place to do this is in the Model's Properties window which you can access when the model is open in the designer. When you change this name and save the model, the ConnectionString name in the config file should change to BAEntities as well. It's a good thing to double check that this happened by looking in the app.config file. Additionally, it will make typing Entity SQL expressions easier as you have to include this container name in every expression.

6.7.1.3. Model Namespace You can change the model's namespace to BAModel so that it's consistent with teh container name.

6.7.2. Compiling and the EDMX file When a project containing an EDM is compiled, the compiler extracts the CSDL, SSDL and MSL sections of the EDMX file and creates the individual schema files.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 164

Return to Table of Contents

6.7.2.1. Schema files are embedded by default By default, these files are embedded into the assembly that is built from the project. Figure 6-11 shows the compiled assembly in Red Gate's Reflector tool, with the embedded files listed under resources. Figure 6-11. The schema files are embedded in the assembly by default.

If you look at the metadata portion of the EntityConnection string that is created by the EDM Wizard, there's a significant notation in there. res://*/BAModel.csdl|res://*/BAModel.ssdl|res://*/BAModel.msl

Much of the functionality in the Entity Framework depends on its ability to read the schema files. The * in the metadata of the connection string indicates that the files can be found in the assembly. Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 165

Return to Table of Contents

6.7.2.2. Splitting out the schema files Having the model in the assembly is convenient when you don't expect the model to change very often after it is deployed. However you may have a scenario where you want to take advantage of the loose coupling of the model. For example, you or your DBA might makes some modifications to the database in a way that the schema changes, but nothing new is introduced that would have an impact on the objects in the application. In this case you would need to update the model so that the database changes are reflected in the SSDL schema. Then, because of this change, you would need to adjust some of the mappings to be sure CSDL objects are mapped correctly to the SSDL. So, in this scenario, the SSDL and MSL layers change, but no change is made to the conceptual layer. You may not want to have to rebuild and redeploy the assembly. Doing so may also affect versioning in your application. While the files are embedded by default, there is an option to have the files exist outside of the assembly. The model has a property called Metadata Artifact Processing. The property is available in the model's Properties window as shown in Figure 6-12. Figure 6-12. . Change the Metadata Artifact Processing to Copy to Output Directory to change how the model's schema files are created during the build process.

Notice the Connection String has changed. The metadata no longer has the * to indicate that the files are embedded. Instead, it shows the relative path of the files. You will find them in the project's output directory, which by default is either the bin\debug or bin \release folder inside the project folder.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 166

Return to Table of Contents

6.7.2.3. Moving the schema files You can put the schema files anywhere that you want them to be. However, you will need to be sure that the connection string points to the correct path. If, for example, you place the files in C:\EDMS, then you'll need to modify the metadata attribute to: metadata=C:\EDMS\BAModel.csdl| C:\EDMS\BAModel.ssdl| C:\EDMS\BAModel.msl

NOTE

While this chapter is about creating a model in a separate assembly, it's useful to be aware of a special case for the metadata attribute. If you create an EDM inside of a web application, because of the way in which web applications are compiled, the path will be affected. The entire metadata attribute will be "metadata=res://*".

Licensed by Dave Olsen

You can learn more about the Entity Connection's metadata attribute in the MSDN Library documentation.

6.8. Chapter Summary In this chapter you went through the steps of creating an Entity Data Model from a more realistic database which you will be using throughout the rest of this book. Then you spent some time cleaning up many of the automatically created entity and property names so that they will be more logical when it comes time to use the model in your applications. You have now prepared an assembly that can easily be referenced from a variety of projects and used in other applications. Because the run-time schema files are embedded into the assembly, it will be even simpler to reuse and share the model. In the next chapter you will write your first Windows applications using this model.

Chapter 7. Data Binding EF in Windows Apps: Part 1 So far you have mucking about with model and snippets of code in a Console application. While there is much more to learn about Entity Framework before you can use it to write nicely layered and architected applications, it might be fun to see Entity Framework in action in some simple applications. Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 167

Return to Table of Contents

But the chapter is not all about fun. You'll write two client applications that perform some basic functions for the BreakAway Adventures staff. The first is a Windows Forms app to view and edit customer's records and view their scheduled trips. Then you will create a Windows Presentation Foundation application which allows users to view, edit and add trips to the BreakAway catalog. In both of these applications, you will explore basic data binding techniques to view and edit the data through the Entity Data Model. You'll bind directly to the results of Entity Framework queries for now just to get some of the concepts. Chapter 19 addresses n-tier Windows Forms applications after you have learned much more about the Entity Framework. In this chapter you will also make some more changes to the model as you hit some walls. While it is preferable to have the model properly defined prior to building an application with it, here we are using the simple, but insufficient, model as a means to better understanding the reasons for implementing particular modeling techniques.

7.1. Create a Windows Forms Application to use the BreakAway Model The goal of this first exercise will be to build a small app to let you view customers and their reservations as well as edit the customers and add new reservations. Figure 7-1 shows this form with a DataGridView to work with the customers, a ListBox control for reservations and a ComboBox for selecting new trips to add to a Customer's reservations.

NOTE

This chapter will not presume that you are familiar with Windows Forms or WPF data binding techniques in the IDE. So you'll get a step by step walkthrough to be sure that you don't get stumped on any of the UI tasks You'll be building up the form in stages, in each stage adding a little more functionality then testing what you've built so far. Figure 7-1. The Windows Forms app you'll be building

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 168

Return to Table of Contents

The first task will be to create a Windows Forms project that uses the assembly you created in Chapter 6. You should add this new project into the same solution where your new model is. That way you can easily reference the model and make changes to it as needed. 1. Add a new Windows Forms Application Project to the solution and give it the name BreakAwayWinForms.

NOTE

The next three steps will be common for any application that needs to use an Entity Data Model that is in a separate assembly. 2. Add a reference to the BreakAwayModel project. To do this, right click the BreakAwayWinForms project in Solution Explorer. Select Add Reference. In the Add Reference Dialog, select the Projects tab. Then select BreakAwayModel and click OK. This will allow the new application to use everything in the model as well as the generated entity classes.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 169

Return to Table of Contents

3. Add references to System.Data.Entity and System.Data.Linq under the .NET tab of Add References. When you created the model in the other project, the wizard automatically pulled in the necessary references to Entity Framework APIs. Your new app will need these references as well, which is why you need to add them manually. 4. Copy the app.config file from the BreakAwayModel project into the new WinForm project. Because you are using the model in the BreakAwayWinForms project, it is this project which will need access to the Entity Connection string. By default, no app.config file is created for a WinForms project. If you had already created an app.config file, then you only need to copy the "BAEntities" connection string element from the model's app.config to this project's app.config. In this case, since the app.config doesn't exist yet, you can cheat by just copying the whole file.

7.2. Use WinForms DataSources to help with Data Binding Data Sources have been a feature of Windows Forms since Visual Studio 2005 and are very convenient way to perform data binding. There are three types of Data Sources – those which bind directly to a database, those which bind to a service and those which bind to objects. In this app, you will be creating Data Sources that bind to objects, specifically, to the entity classes that were dynamically generated from the EDM. An Object Data Source won't bind to the entire EntityContainer, but to one individual class. Additionally, while a Data Source that is derived from a database will trigger the interaction with the database, an Object Data Source will not. It provides the schema of the classes to the controls that you are binding data to and it provides the ability to interact with the objects. You will have to write the actual code that populates the Data source at runtime. Using the Data Sources is a great example of how the EDM and Entity Framework plug right into the existing tools in Visual Studio.

NOTE

This is not to say that EF plugs into all of the existing tools, because you will find that there are still some gaps such as the inability for the Microsoft Report control to work with hierarchical data. More on this later.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 170

Return to Table of Contents

7.2.1. Creating an Object Data Source for a Customer Entity The Object Data Source you will need is for the Customer class. Here's how to create it. 1. From the Visual Studio menu, select the Data menu item, then Show Data Sources from that menu's drop down to open the Data Sources window ( Figure 7-2). Figure 7-2. The Data Sources window before the new Data Source has been created.

2. Click the Add New Data Source hyperlink to open the Data Source Configuration wizard. 3. Select Object in the Choose Data Source Type window, then click Next. 4. The next window will present you with the available assemblies in the current Solution. Expand the BreakAwayModel assembly to reveal the BAGA namespace then expand that to reveal the entity classes as in Figure 7-3. Figure 7-3. The classes from your model are available for creating a data source.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 171

Return to Table of Contents

5. Select Customer then click Next. 6. Click Finish. The Customer Data Source will now display in the Data Sources window. Expand the Customer Data Source to see its properties. Notice that the navigation properties are there including the Reservations with its properties as shown in Figure 7-4. Entity Framework classes are built to expose their navigation properties for data binding. Figure 7-4. The Customer Data Source includes its navigation properties.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 172

Return to Table of Contents

7.2.1.1. Leaning on the Navigation Properties An interesting thing about the Customer entity and class is that its scalar properties aren't' terribly interesting — ContactID, CustomerType and InitialDate. While the Customer entity represents Contacts who are Customers, it depends on the related Contact entity to provide name information and to give you access to the contact's Addresses. Customer relies on its relationship to Reservations to supply details about what makes them a customer — all of the trips they have taken or are planning to take. Even their Activity and Destination preferences are navigation properties. If you were to create a DataGridView from the Customer Data Source, the only properties that would display by default are the scalar properties. Instead, you can leverage the related Contact and Reservations to build a more useful form.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 173

Return to Table of Contents

7.2.2. Getting the Customer details onto the form Data Sources allow for some very convenient drag and drop operations. You don't want to drag the entire customer object, because that will only result in a DataGridView with very little information. Instead you'll want to drag the properties and you can only do those one at a time. Since we'll want most of the Customer's Contact details on the form, you can select Contact in the Data Source window and drag it onto the form. Customer is a property, so it's possible to get all of its details at once. The impact of this is that a new Navigation toolbar will be created as well as the appropriate controls for the various properties — TextBoxes for the integers and strings and DateTimePicker controls for the data field. Additionally, on the perimeter of the design window, you'll see that a CustomerBindingSource and a CustomerBindingNavigator property were added. These are components that enable binding to Data Source in Windows Forms. The BindingSource will coordinate the form fields with the data. The BindingNavigator coordinates the actions of the toolbar (navigation, inserting, deleting and updating) with the BindingSource. Next, expand the PrimaryActivity property then drag its ActivityName to the form. You'll need to modify the label so that it says "Primary Activity". Do the same for the other preferences. Finally, add the Customer.InitialDate field. This represents the first date the contact became a customer which is useful in case the person was on a mailing list for a while before finally becoming a customer. If you care to line up and organize the fields on the form, it will look something like this after you have added these fields. Figure 7-5. The form with the first bits of data binding.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 174

Return to Table of Contents

7.2.3. Adding the code Now you'll need to execute a query when the form loads to retrieve the customers along with their related data. You will bind these query results to the query results You'll get to take advantage of the Eager Loading you learned about in Chapter 5 by using a number of Include methods in this query. The reason for this is that the form relies on five navigation properties. In the Form's Load event add the code from Example 7-1. The use of ObjectResult and Execute will be explained shortly. Example 7-1. Querying for Customers in the Form Load VB Dim context = New BAGA.BAEntities Dim customers As ObjectResult(Of BAGA.Customer) = _ context.Customers _ .Include("Contact") _ .Include("PrimaryActivity") _ .Include("SecondaryActivity") _ .Include("PrimaryDestination") _ .Include("SecondaryDestination") _ .Include("Reservations.Trip.Destination") _ .Execute(Objects.MergeOption.AppendOnly) CustomerBindingSource.DataSource = customers C# var context = new BAGA.BAEntities(); ObjectResult customers= context.Customers.Include("Contact") .Include("PrimaryActivity") .Include("SecondaryActivity") .Include("PrimaryDestination") .Include("SecondaryDestination")

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 175

Return to Table of Contents

.Include("Reservations.Trip.Destination") .Execute(Objects.MergeOption.AppendOnly); customerBindingSource.DataSource = customers;

The query is written to ensure that all of the necessary related information is retrieved from the data store. Each Customer in the results will be a graph shaped as shown in Figure 7-6. Figure 7-6. The resulting Customer graph

7.2.3.1. Performance Considerations This particular query is not designed for efficiency, but to give you an idea of how the Include method works and how the data binding implements related data. Notice that the query does not even bother to filter the data. The resulting SQL query and the amount of data returned may make you gasp. So while it's very important to be aware that this is not a best practice, its handy query for this lesson based on what you've learned so far. There are quite a lot of Include methods in this query. Most of the related entities are small. Activity and Destination have only an ID field and a Name field. Reservations and Trip Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 176

Return to Table of Contents

don't have a lot of fields either. But there will be a lot of redundant data sent back to the application. Each customer who has Madagascar selected as their Primary or Secondary 7Destination will cause that row of data to be transmitted back to the application. If one hundred people favor that locale, then one hundred copies of that row will be returned. As Object Services materializes objects from those rows, it will recognize the redundancy and not create multiple copies of that particular object in memory, so on the application side the query results will be efficient. Later in this chapter, we'll look at more efficient ways to return the related data without this redundancy.

7.2.4. Testing the sample Go ahead and run what you've built so far. As you use the navigation toolbar to move from one customer to another, you'll be able to see that all of the navigation properties automatically change as well. Figure 7-7. Customer's Navigation Properties on display

There is one caveat. In the form's current design, edits to the navigation properties won't have the desired effect. If you edited the PrimaryActivity field, you won't be changing which Activity the Customer is related to but you will actually change the value of the Activity's record in the data store. We'll see why that is and fix the form shortly to do that properly.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 177

Return to Table of Contents

7.2.5. Entities, BindingSources and a very important Rule When you bind the query results to the BindingSource, the BindingSource will act as an agent to coordinate between the entities, the fields and the navigation tool bar. The BindingSource will update the entities when a change is made in the form's fields. In this example, when it's time to have the Entity Framework send the entity changes to data store, all of the change information will be available. But the code in Example 7-1 follows a very specific rule. The Customer query uses the Execute method. The Execute method was introduced in Chapter 3, Foundations of Querying, with a teaser about using it in data binding. Execute returns an ObjectResult(Of T); in our example, ObjectResult(Of Customer).

NOTE

While most of the code samples you have seen so far have taken advantage of implicitly typed variables, the customers variable was explicitly typed in this code so that you would be clear about the fact that the type is an ObjectResult. ObjectResult is an enumerable collection that has special features to enhance data binding and the binding's ability to interact with the ObjectContext. While you may find that some updates and additions will work properly even if you returned a List(Of Customer), you may also get unexpected results. One bad result that you can count on is that when you delete an item, no delete command will be sent to the database. With an ObjectResult, the delete will work as expected.

NOTE

As you dig deeper into Object Services in the next chapter, you'll have a better understanding why the delete command won't get to the database in this scenario. Execute takes a MergeOption parameter. MergeOption specifies what to do if the query results already exist in the context. It's possible to execute many queries against the same context (or even re-execute one query multiple times). If duplicate data is pulled down from the data store, you are able to control how those duplicates are handled. In this case, the AppendOnly option tells the context only to add in entities that don't already exist in the context. This way you won't have to worry about overwriting changes you have made. There's more to learn about MergeOptions in the Object Services chapter which is next.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 178

Return to Table of Contents

There's also another caveat with using ObjectResults which you will learn about when you encounter it in the upcoming WPF sample.

7.2.5.1. Beware of Binding Directly to a Query If you bind a LINQ query or ObjectQuery directly to a BindingSource.DataSource property, you'll get your data, but the query will execute every single time the user moves to a new Customer. Imagine querying for 100 customers every time the user moves to a new Customer.

NOTE

If you work with highly concurrent data and want to be sure that each record has fresh data, then you would be better off using a query that returns a single Customer. Then you can bind the query directly to the BindingSource.DataSource property and have the query automatically executed each time the user moves to another Customer record.

7.3. Adding the Reservations Entity Collection to the form Now it's time to get the Reservations onto the form. The Reservation entity presents the same problem as the Customer in that most of the best information is in its navigation property, Trip. If you dragged the Reservations property onto the form, the default control, DataGridView, at runtime, the Reservations are displayed as shown in Figure 7-8. Figure 7-8. The default grid for the Reservations Navigation property

Even if you edited the DataPropertyName of the Trip column to be "Trip.StartDate", Windows Forms is not able to work out that navigation. This is not a problem specific to Entity Framework, but a result of how the DataGridView functions.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 179

Return to Table of Contents

7.3.1. Displaying the properties of Reservation.Trip in the Grid There is a known way to display properties of related objects in DataGridView and you can take advantage of that here. The grid will be useful if it displays the Reservation Date, the Start and End Dates of the Trip and the Destination of the trip. Destination comes from a navigation property of the Trip entity, so first we'll need to modify the columns in the grid. Edit the grid's columns. You can make the ReservationID's Visible property false, the remove the Customer, Trim and Payments columns. Add three new TextBox columns named tripStartColumn, tripEndColumnand destinationColumn. Make sure their ReadOnly property is True. The trick for displaying the navigation properties is in the code. You must override the individual cells as the grid is being rendered for display and the place to do this is in the DataGridView.RowPrePaint event. Example 7-2 shows how to do this.

NOTE

In C#, access this event from the Events page of the grid's Properties window. In VB, you can do the same or access the event in the code window by choosing ReservationsDataGridView from the Class Name DropDown and then RowPrePaint from the Method Name DropDown.

Example 7-2. Forcing the DataGridView to display navigation properties VB Private Sub ReservationsDataGridView_RowPrePaint _ (ByVal sender As Object, ByVal e As _ System.Windows.Forms.DataGridViewRowPrePaintEventArgs) _ Handles ReservationsDataGridView.RowPrePaint 'get a reference to the reservation currently being painted Dim res = _ CType(ReservationsBindingSource.Item(e.RowIndex),BAGA.Reservation) 'push the reservations's navigation properties into the correct cells With ReservationsDataGridView .Rows(e.RowIndex).Cells(tripStartColumn.Index).Value = _ res.Trip.StartDate.ToShortDateString .Rows(e.RowIndex).Cells(tripEndColumn.Index).Value = _ res.Trip.EndDate.ToShortDateString .Rows(e.RowIndex).Cells(destinationColumn.Index).Value = _ res.Trip.Destination.DestinationName End With End Sub C# private void reservationsDataGridView_RowPrePaint (object sender, DataGridViewRowPrePaintEventArgs e) { //get a reference to the reservation currently being painted

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 180

Return to Table of Contents

var res = (BAGA.Reservation)(reservationsBindingSource[e.RowIndex]); //push the reservations's navigation properties into the correct cells var grid = reservationsDataGridView; grid.Rows[e.RowIndex].Cells[tripStartColumn.Index].Value = res.Trip.StartDate.ToShortDateString(); grid.Rows[e.RowIndex].Cells[tripEndColumn.Index].Value = res.Trip.EndDate.ToShortDateString(); grid.Rows[e.RowIndex].Cells[destinationColumn.Index].Value = res.Trip.Destination.DestinationName; }

7.3.2. Test out the new version of the sample Notice that you don't have to add any more querying or binding code into the form load. The fact that you have already bound the Customers to the BindingSource is enough. The BindingSource will work out all of the relationships. In the form, as you navigate from one customer to the next, that customer's reservations will be displayed in the grid. Figure 7-9. The sample with Reservations added to the form

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 181

Return to Table of Contents

NOTE

The Trip Start and End dates were formatted in the RowPrePaint event using ToShortDateString. To format the ReservationDate column, you'll need an additional line of code in the Form Load event. After renaming the column to resDateColumn, the formatting code is as follows: VB ReservationsDataGridView _ .Columns(resDateColum.Index) _ .DefaultCellStyle.Format = "d" C# reservationsDataGridView .Columns[resDateColumn.Index] .DefaultCellStyle.Format = "d";

7.3.3. Remember, this is a demo – not a best practice Because of the convenient but inefficient query, all of the Customer objects with all of their Reservations and related Trip data are in memory. So in this example, the application does not need to return to the database to retrieve additional data as you move from one Customer to the next. In a properly designed application, you will need to be more diligent about retrieving only the data that the user will need and be considerate about balancing the client side resources with the trips to the server and the amount of data being transmitted based on your scenario.

7.4. Editing Customers So far, you have been using the form to view data. What about adding or editing? The BindingSource supports editing, but you'll need to make a few small modifications to the form and the code to get this functionality. We'll start with Editing.

7.4.1. Enable the Save button By default, the navigation toolbar disables the Save button when the toolbar is first created. Right click on the button and check the Enabled property in the context menu.

7.4.2. The ObjectContext keeps track of entity changes Before you can add the method to save data, there's an important change to make in the existing code. Currently, you are instantiating the BAEntities ObjectContext in the Form Load event. The context is not available outside of the event.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 182

Return to Table of Contents

When you query data with the context, by default, that resulting entities are managed by the context which keeps track of changes made to those entities. You can then use the ObjectContext.SaveChanges method to save those changes back to the data store. While you will learn much more about this later on in the book, you'll need to be aware of the fact that only the context that is tracking the changes is able to save them. You can't instantiate a new context and expect it to save changes to the entities that we're working with in the form. It won't know anything about them. Therefore, it is important to be sure that when you call SaveChanges, you are working with the very same context that you used to retrieve the data. To do this in the form, you need to declare the context in the form declarations, not within a method. This way all of the form's methods can work with the same context and you will be able to SaveChanges in the Click event of the Save button.

7.4.3. Changing the scope of the ObjectContext Just below the line of code that declares the Form, you can add the code to declare the context. VB Public Class Form1 Private context As BAGA.BAEntities C# public partial class Form1 : Form { BAGA.BAEntities context;

In the Form's Load event, change the code that declared and instantiated the context so that it only instantiates the context. VB context = New BAGA.BAEntities C# context = new BAGA.BAEntities();

7.4.4. Adding the Saving logic to the Save button In the form's Design view, double click the Save button to get to its Click event handler. Add the SaveChanges code into the Click event. VB context.SaveChanges C# context.SaveChanges();

That is the complete code for saving all of the entity changes! There is no connection code, no need to build commands and no need to worry about what entities are being saved or Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 183

Return to Table of Contents

what types of changes are being made. Object Services reads all of the change information that it has kept track of for the entities that it is managing and works out the proper commands (Insert, Update or Delete) then executes them. If the model had any function mapping, Object Services would use stored procedures to perform the changes on the entities that have functions mapped to them.

7.4.5. Test out a Customer Edit In its current state, you can test out editing Customers. There is another tweak necessary before you can edit the navigation properties and yet another before you can add a new customer. So for now try editing and saving the name fields of a customer.

7.5. Editing the Navigation Properties (and trimming down the query) The next stage of building up the functionality in this form is to make it possible to edit the other Navigation properties. You are already able to edit the Contact navigation property because it has a one to one relationship with the customer. It is essentially an extension of the Customer. The preference properties, PrimaryActivity, etc, are values selected from a list of possible items. You'll need two things to be able to change the selections. The first is access to a complete list of the items (Activities and Destinations) and the fields should be represented as some type of selection control. We'll use a ComboBox.

7.5.1. Reorganizing the data retrieval Currently the only Activities and Destinations in memory are those which are attached to the Customers and this may not even be all of the available options. Instead, we'll need the full lists so we'll need a new query to retrieve all of the Activities and another for all of the Destinations. This will add a big benefit to the application. When the Activities and Destinations are queried, their objects are all stored in memory. More specifically, they will be managed by the ObjectContext. This means that it won't be necessary to include the Activity and Destination data in the Customers query. When the Customers are queried, they will still have the Reference EntityKeys even if they don't have the actual related entities. Figure 7-10 shows the PrimaryActivity and PrimaryActivityReference properties of a Customer which was queried without any of its related data..

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 184

Return to Table of Contents

Figure 7-10. Reference EntityKeys can exist without the related entity as with the Customer object

When the context creates the customer, if the Activity object with that same EntityKey is already in the context, they will be hooked up. The same happens if you were to query the Customers first and then the Activities. So now you can add in the new queries and trim down the Customers query so that it doesn't pull all of that extra data out of the database and over to the application. The new queries will be method queries so that you can keep your various querying skills tuned up. At the same time, we'll create two new form level variables to contain the Activities and Destinations. Add the new activities and destinations variables to the form declarations as shown in Example 7-3. Example 7-3. Adding variables to hold the new lists VB Public Class Form1 Private context As BAGA.BAEntities Private activities As List(Of BAGA.Activity) Private destinations As List(Of BAGA.Destination) C# public partial class Form1 : Form { BAGA.BAEntities context; List activities; List destinations;

Next, add the new queries shown in Example 7-4 into the form load and modify the existing customers query to remove the extraneous navigations. Notice that Destination is also removed from the Reservations.Trip navigation path. Trip will also be able to find its related Destinations in the context after they are created from the Destinations query.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 185

Return to Table of Contents

Example 7-4. Querying for the list data VB Private Sub Form1_Load _ (ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load context = New BAGA.BAEntities activities = context.Activities _ .OrderBy(Function(a) a.ActivityName).ToList destinations = context.Destinations _ .OrderBy(Function(d) d.DestinationName).ToList Dim customers = context.Customers.Include("Contact") _ .Include("Reservations.Trip") _ .Execute(Objects.MergeOption.AppendOnly) C# private void Form1_Load(object sender, EventArgs e) { context = new BAGA.BAEntities(); activities = context.Activities .OrderBy((a) => a.ActivityName).ToList(); destinations = context.Destinations .OrderBy((d) => d.DestinationName).ToList(); var customers = context.Customers.Include("Contact") .Include("Reservations.Trip") .Execute(Objects.MergeOption.AppendOnly);

NOTE

You can run the application again if you want to see that all of the reference properties are still intact. Notice that the example uses ToList on the new queries instead of Execute. This data will only be used for pick lists and will not be edited directly, so you don't have to worry about the BindingSource being able to pass along change information for Activities and Destinations to the context.

7.5.2. Replacing the Navigation Property TextBoxes with ComboBoxes Now that the data for the lists exists, you can change the controls for PrimaryActivity and the other navigation properties to ComboBoxes so that it will be possible to edit a Customer's preferences. You can bind the ComboBox controls in code or in the UI. Since there are four properties to change, let's do both methods so that you can learn each one. Replace the TextBox controls for the four target properties with ComboBox controls giving them names to help you differentiate them. The FillCombos method in Example 7-5 performs the standard bindings for a ComboBox and additionally binds them to the PrimaryActivity and PrimaryDestination navigation properties of the Customer. Notice that the first argument for the new binding is SelectedItem. You may be more familiar with Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 186

Return to Table of Contents

using "Text" in that argument. SelectedItem will cause the control read the entire Activity object attached to the Customer and work out how to match it up with the items in the ComboBox. Example 7-5. Code for filling two of the ComboBoxes VB Private Sub FillCombos() With PrimaryActivityComboBox .DisplayMember = "ActivityName" .ValueMember = "ActivityID" .DataSource = activities .DataBindings.Add _ (New Binding("SelectedItem", CustomerBindingSource, _ "PrimaryActivity", True)) End With With PrimaryDestinationComboBox .DisplayMember = "DestinationName" .ValueMember = "DestinationID" .DataSource = destinations .DataBindings.Add _ (New Binding("SelectedItem", CustomerBindingSource, _ "PrimaryDestination", True)) End With End Sub C# private void FillCombos() { PrimaryActivityComboBox.DisplayMember = "ActivityName"; PrimaryActivityComboBox.ValueMember = "ActivityID"; PrimaryActivityComboBox.DataSource = activities; PrimaryActivityComboBox.DataBindings.Add (new Binding("SelectedItem",customerBindingSource, "PrimaryActivity", true)); PrimaryDestinationComboBox.DisplayMember = "DestinationName"; PrimaryDestinationComboBox.ValueMember = "DestinationID"; PrimaryDestinationComboBox.DataSource = destinations; PrimaryDestinationComboBox.DataBindings.Add (new Binding("SelectedItem",customerBindingSource, "PrimaryDestination", true));

Run the application again if you want to see the ComboBoxes getting populated so far. The other ComboBoxes will be bound in the UI. To do this, you will first need to create a new Object Data Source for the BAGA.Activity class and one for BAGA.Destination then in the Form Load, bind those new DataSources to the list variables VB ActivityBindingSource.DataSource = activities DestinationBindingSource.DataSource = destinations C# customerBindingSource.DataSource = customers; destinationBindingSource.DataSource = destinations;

Using the Task window, you can fill out three of the four properties for the each ComboBox. The combo properties for the SecondaryActivity are shown in Figure 7-11.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 187

Return to Table of Contents

Figure 7-11. Bind some of the properties through the ComboBox's Task window.

The last property is not filled because you will need to set the SelectedItem property, not the Selected Value. Do this in the Properties window as shown in Figure 7-12. Figure 7-12. Bind the ComboBox selection using SelectedItem, which is available in the ComboBox Properties window

7.5.3. Test the sample again Now you can view, edit and save these properties along with the rest of the Customer data. Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 188

Return to Table of Contents

Figure 7-13. Editing the navigation properties with pick lists

7.6. Adding new Customers There's one last task that we'll take on in this Windows Form before moving on — adding new Customers. The Data Sources don't handle the related entities quite as seamlessly when adding as they do when editing, so we'll have to add a little bit of code to make it work. When you click on the plus sign to add a new Customer, a new Customer is added to the CustomerBindingSource. But you also need a new Contact entity to be created at the same time. The BindingSource has an AddingNew event, but this occurs before the new entity is created. The very next event to fire is CurrentChanged as the BindingSource moves it's pointer to the newly created Customer. In the CurrentChanged event you can add the new contact and set any other properties necessary. Here you will have your first opportunity to see how to create new entities in code, to create a relationship and to be sure the new entity is being managed by the context. Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 189

Return to Table of Contents

7.6.1. From Toolbar to BindingSource to Context We've established that clicking on the icon adds a new Customer to the BindingSource, and that the CurrentChanged event is your first opportunity to work with the new Customer entity. But the CurrentChanged event is hit any time the BindingSource points to a different Customer. You'll need a way to discern the newly added Customer from those which already existed in the BindingSource. One way might be to check the Customer's ContactID, because it will not have been created yet. But if the user has added a number of Customer's prior to saving, ContactID=0 will not necessarily mean that user just clicked the Add New icon. Until you have more tools in your Entity Framework tool belt, the best way to determine a newly added Customer at this point is to use a flag to identify that a new customer is being added to the BindingSource. Once that is in place you will need to do the following for new customers: 1. 2. 3. 4. 5.

Create a new contact object Add the contact to the new Customer Set necessary defaults on the Contact Set necessary defaults on the Customer Set the flag to false

NOTE

In Chapter 9, Customizing Entities, you will learn how to add business logic to entities and these types of steps won't be necessary — especially not in the User Interface.

7.6.1.1. Add the code to ensure that new customer's are created properly Add the adding Boolean variable to the Form's declarations. Public Class Form1 Private context As BAGA.BAEntities Private activities As List(Of BAGA.Activity) Private destinations As List(Of BAGA.Destination) Private adding As Boolean C# public partial class Form1 : Form { BAGA.BAEntities context; List activities; List destinations; bool adding;

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 190

Return to Table of Contents

In the CustomerBindingSource.AddingNew event, set the flag to True. VB Private Sub CustomerBindingSource_AddingNew _ (ByVal sender As Object, _ ByVal e As System.ComponentModel.AddingNewEventArgs) _ Handles CustomerBindingSource.AddingNew adding = True End Sub C# private void customerBindingSource_AddingNew (object sender, AddingNewEventArgs e) { adding = true; }

In the CurrentChanged event, you'll check the flag and if it is true, perform the steps outlined above to the new Customer. VB Private Sub CustomerBindingSource_CurrentChanged _ (ByVal sender As Object, ByVal e As System.EventArgs) _ Handles CustomerBindingSource.CurrentChanged If _adding Then Dim newcust = CType(CustomerBindingSource.Current, BAGA.Customer) If newcust.Contact Is Nothing Then newcust.Contact = New BAGA.Contact newcust.Contact.ModifiedDate = Now newcust.Contact.AddDate = Now End If newcust.InitialDate = Now _adding = False End If End Sub C# private void customerBindingSource_CurrentChanged (object sender, EventArgs e) { if (adding) { var newcust = (BAGA.Customer)customerBindingSource.Current; if (newcust.Contact == null) { newcust.Contact = new BAGA.Contact(); newcust.Contact.ModifiedDate = Now; newcust.Contact.AddDate = Now; } newcust.InitialDate = Now; adding = false; } }

There is one last line of code that you'll need for saving newly added customers. It's not uncommon for the BindingSource to leave an entity in its "edit state". With entities, it means that the changes in the UI won't get pushed into the entities and therefore SaveChanges will not see the need to do any updates to the database. BindingSource.EndEdit will ensure that the UI changes are registered with the entities. Add it to the SaveItem button's click event, just before SaveChanges is called. VB Private Sub CustomerBindingNavigatorSaveItem_Click _ (ByVal sender As System.Object, ByVal e As System.EventArgs) _

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 191

Return to Table of Contents

Handles CustomerBindingNavigatorSaveItem.Click CustomerBindingSource.EndEdit() context.SaveChanges() End Sub C# private void customerBindingNavigatorSaveItem_Click (object sender, EventArgs e) { customerBindingSource.EndEdit(); context.SaveChanges(); }

7.6.1.2. Test out the Add Customer features of the form Run the form again and add a new customer. You'll be able to enter name and preference information and save the record. Because the context is keeping track of adds and edits, it is possible to make changes to multiple records before hitting the Save button. When you do, all of the changes you have made to the list of Customers, whether it's adding or editing, will get sent to the database. The best way to ensure that its working is to stop the application after you have saved your changes, then start it again. This will force it to requery the database and you can verify that the changes were definitely persisted to the store. Not all of the form features will work. You will run into problems if you attempt to delete a customer because of the constraints in the database. You will be learning how to do all of these types of functions with your entities, how to add business logic, how to write layered applications and more. There are plenty of features you could add to this form to make it even more functional, but it's time to move on to a very different type of client side data binding in Windows Presentation Foundation.

7.7. Data binding with WPF Applications For the WPF data binding example, you'll focus on interacting with Trips and their details — Destination, Lodging, Activities and the Equipment necessary for the Activities. You will also get a chance to see how many to many relationships work both for data retrieval and updates. If you've never created a WPF app before, this will be a useful, while simple, introduction. It will be a bit of a dive into the not-so-shallow end of the WPF pool, but the code samples should provide sufficient buoyancy. If you are looking for tips on how to make WPF perform its many shiny tricks, a data access book is not the place to look. Currently there are no data binding controls for WPF "in the box" with Visual Studio 2008. Third party control developers are a great source for WPF data-binding controls. But for this walkthrough, we'll stick to what's available directly with Visual Studio. Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 192

Return to Table of Contents

NOTE

Windows Presentation Foundation is a much younger technology than Windows Forms and therefore does not have the suite of data binding controls available for Windows Forms. The WPF sample in this chapter will use controls that are available in Visual Studio 2008. Microsoft is committed to providing them and currently provides a DataGrid in the WPF Toolkit available on their code sharing site, CodePlex, at codeplex.com/ wpf. There are quite a number of 3rd party providers who have written controls for WPF including DataGrids and others that do data binding.

7.7.1. The WPF Form The purpose of this form will be to edit trips that exist in the BreakAway catalog. Trips are defined by a Destination, a start and end date, a price, the Lodging and a list of Activities. The form that you will build is shown in Figure 7-14. Figure 7-14. The WPF form for managing BreakAway's Trips catalog

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 193

Return to Table of Contents

There are a slew of controls involved in this form. You'll learn how to bind ListBoxes and TextBoxes and how to have them interact with one another and some tricks that you'll need to know for doing all of this with Entity Framework.

7.8. Create the new project We'll begin by creating a new WPF project, adding the references to use the model and getting all of the controls onto the form. Create this project in the same solution where you created the model and the Windows Form application. 1. Create a new WPF project in the same solution. 2. Add a reference to the BreakAwayModel project and to System.Data.Entity as you did for the previous application. 3. Copy the app.config file from the Model project into this project. 4. Remember, this is just a cheat to quickly get the ConnectionString into the current application. 5. Drag a WPF ListBox control from the Toolbox onto the default form. This will be the ListBox for displaying the trips. 6. Change the ListBox's name to lstBoxTrips.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 194

Return to Table of Contents

NOTE

If you haven't used WPF before, you might appreciate that the name property is at the top of the control's Properties window.

7.8.1. Add code to query the Trips Adding events to WPF is the same as for Windows Forms. In C#, you can use the Events page of the Properties windows. IN VB you can do the same or use the Class Name and Method Name drop downs in the Code Window. 1. Declare variables for the form. 2. Like the previous app, you'll need a context and some variables to contain the selection lists. You can add an Imports or using statement for the BAGA namespace so you don't have to type it repeatedly. While you're at it, add the System.Data.Objects namespace in as well. It will reduce some typing later on. VB Imports BAGA Imports System.Data.Objects Class Window1 Private context As BAEntities Private activities As List(Of Activity) Private destinations As List(Of Destination) Private lodgings As List(Of Lodging) Private trips As List(Of Trip) C# using BAGA; using System.Data.Objects; using System.Collections.ObjectModel; namespace BreakAwayWPFCSHarp { public partial class Window1 : Window { private BAEntities context; private List activities; private List destinations; private List lodgings; private List trips;

3. In the Window.Loaded event handler, add the code for retrieving the Trips as well as the related selection lists. 4. The selection lists can be returned as generic lists, but use the Execute method to return Trips as ObjectResults because the Trips will be edited as well as data bound. VB Private Sub Window1_Loaded _ (ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) _ Handles Me.Loaded context = New BAEntities

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 195

Return to Table of Contents

activities = context.Activities _ .OrderBy(Function(a) a.ActivityName).ToList destinations = context.Destinations _ .OrderBy(Function(d) d.DestinationName).ToList lodgings = context.Lodgings _ .OrderBy(Function(l) l.LodgingName).ToList Dim tripResults = context.Trips _ .OrderBy("it.Destination.DestinationName") _ .ToList lstBoxTrips.ItemsSource = tripResults End Sub C# private void Window_Loaded (object sender, System.Windows.RoutedEventArgs e) { context = new BAEntities(); activities = context.Activities .OrderBy(a => a.ActivityName).ToList(); destinations = context.Destinations .OrderBy(d => d.DestinationName).ToList(); lodgings = context.Lodgings .OrderBy(l => l.LodgingName).ToList(); trips = context.Trips . .OrderBy("it.Destination.DestinationName").ToList() lstBoxTrips.ItemsSource = trips; }

There are a few things to note about this code. First, it's not using the Execute method. Since we're no longer using the Object Data Source we can go back to using ToList. The other notable code is the ItemsSource property. This is the method that WPF uses to binds list to controls rather than DataSource.

7.9. XAML's Role in Data binding Although the code identifies the ItemsSource, the designer will need to know some more information about how to present the data. Data binding in WPF is very different than WindowsForms. On the design side, WPF is made of controls within controls within controls. To get the first ListBox to display the data that you set to its ItemsSource property, you'll need to do a few things to the XAML. For first-time WPFers, the following section will build up the XAML for the ListBox step by step to explain all of the working parts.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 196

Return to Table of Contents

7.9.1. Binding with the ListBox The XAML for the ListBox that you put on the form starts out with only the name and its margins.

NOTE

Your XAML may be a little different than what's displayed in these examples because the positioning will not be the same. Not only will your margin values be different, but depending on the placement of your controls, you may have attributes such as VerticalAlignment or HorizontalAlignment. Don't worry about those positioning differences from the examples you'll see here. Focus on the binding. Next you will need to define what the rows will look like. This is done with a control called an ItemTemplate.

Within the ItemTemplate, you will use a DataTemplate because you are binding to a set of data.

Inside of the DataTemplate, you will need two TextBoxes — one to display the DestinationName and another to display the StartDate. A DataTemplate can only contain a single child. Therefore, we'll use a StackPanel (container) control as the single child and then place the TextBox controls inside the StackPanel. This seems a little tricky, but it is the commonly used method.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 197

Return to Table of Contents

StackPanel's are Vertical by default. Since we want the Destination and Date to be side by side, Orientation is explicitly set to Horizontal. Finally, you need to display data in the TextBlocks. This is where the data binding finally comes in. The Text value uses specific syntax. "Binding" indicates that it will be getting its data by way of Binding, rather than hard-coded into the List. "Path" refers to the name of the property within whatever it is bound to and StringFormat defines how to format the string if you don't want to see the default format.

Notice that the Path of the first TextBlock is Destination.DestinationName. WPF will read the Trip.Destination navigation property and get to the DestinationName. Add the ItemTemplate and all of its children shown in the final example to the XAML in Design view. You can type it directly into the XAML or drag the controls from the Toolbar. The TextBlock Text values can be typed directly into the XAML.

7.9.2. Test the Example You've got enough to see some action already. Run the form to see the Trip Destinations and StartDates listed in the ListBox. Because of all of the typing in XAML, it's very easy to make a typo. While some types of typos will result in an exception being thrown, quite often there will be no typo but you won't see the results you expect. If during your testing controls are empty when they shouldn't be, go back and check to be sure you've got the correct control names and property names typed in.

7.10. Selecting a Trip and Seeing its Details The next step for the form is to view Trip details. On the form shown in Figure 7-14, you can see that the Start and End Dates are shown in textboxes on the form along with the

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 198

Return to Table of Contents

Destination and Lodging which are displayed in ComboBoxes. The ComboBoxes will eventually be used for editing Trips as well. WPF's binding goes far beyond binding data to controls. You can also bind controls to each other, creating dependencies between them. We'll use this feature to link the TextBox controls to the ListBox. The TextBox controls will obtain their content from the ListBox's selected Trip. Drag two TextBox controls (not TextBlock) and two ComboBox controls onto the form. Arrange them similar to the example and change their names to txtStart, txtEnd, cboDestination and cboLodging.

7.10.1. Binding the TextBox controls to the ListBox The original XAML of the txtStart controls will look like this.

You'll be adding a Binding element as a child of the each TextBox which means that you'll need to remove the slash at the end of the control so that you can add the TextBox closing element after the Binding. Here's what the txtStart and txtEnd controls will look like after adding the Binding elements.

NOTE

In the ListBox you added a binding into the Text property of a TextBlock. Here you are using a Binding element and the syntax of the Path and its StringFormat are different when used this way.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 199

Return to Table of Contents

7.10.2. Binding the ComboBox controls to the ListBox and to the data Binding a WPF ComboBox is similar to a Windows Forms ComboBox in that you need to set the source (ItemsSource) a set of data, identifying the value and display properties, and you need to identify what source provides its value. We'll bind to the ItemsSource in code, just as you did for the ListBox. Then we'll use XAML to provide the rest of the information as you just did for the TextBox. First to the code. In the Window.Loaded event, bind the results of the Destinations and Lodgings queries to the ComboBoxes. You can add this right below the code for binding the lstBoxTrips control. VB cboDestination.ItemsSource = destinations cboLodging.ItemsSource = lodgings C# cboDestination.ItemsSource = destinations; cboLodging.ItemsSource = lodgings;

In the XAML, you will add more attributes to the ComboBox controls, rather than add a child element as you did for the TextBoxes.

The DisplayMemberPath and SelectedValuePath attributes refer to the properties of the list of Lodgings that you bound the combo to in code. SelectedValue gets the LodgingID from the currently selected Trip in the ListBox. Here is the XAML for the ComboBox that displays the Destination of the selected Trip.

7.10.3. Test the Sample Now you're form is starting to get interesting. When you run the application, you're the Start and End Date boxes and the Combos should synch up to whatever trip is selected in the ListBox as shown in Figure 7-15. Figure 7-15. Figure Caption Text Goes Here

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 200

Return to Table of Contents

There are still three more tasks ahead — viewing the Activities for a trip, editing trip details and adding new trips.

7.11. Adding the Activities EntityCollection to the mix The Activities property is an EntityCollection and needs to be displayed in a control that can display sets. We'll use another ListBox.

7.11.1. The *:* Relationship between Trips and Activities Activities and Trips are joined in a many to many relationship. While EF is able to query across this type of relationship and coordinate inserts, updates and deletes without you having to work directly with the Join table, there is one thing that EF is unable to do with this type of relationship. In previous examples, you have seen how Object Services can automatically wire up related objects that are in the context. It will find entities that are related and build graphs between them. You took advantage of this in the Windows Forms application above. Because the Activities and Destinations were being returned in their own queries, you were able to remove the Include paths to the Customer preference properties. In the Window.Loaded event for this WPF form, you have a query that returns a list of Activities. This will be used as a pick list when you create a new Trip. So since those activities are already in the cache, it would make sense that they will automatically be wired Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 201

Return to Table of Contents

up to the existing trips. But they aren't. This is expected behavior and you'll either need to load the related data with Include or Load or manually attach the entities. In this sample, you will use an Include. You'll learn more about this in Chapter [X], Relationships and Associations.

NOTE

ObjectServices can only do the automatic wiring of related entities when one of the ends of the relationship has an EntityReference property that points to the other end. Because both the Activities property of Trip and the Trips property of Activity are EntityCollections, the relationship information that is needed to bind them doesn't exist within either entity. That is why the graph needs to be explicitly created with one of ObjectServices methods for joining related entities.

7.11.2. Modify the code to eager load the related Activities The bottom line is that you need to change the Customer query in the Window.Loaded event. Add an Include method to pull in the Activities. VB trips = context.Trips.Include("Activities") _ .OrderBy("it.Destination.DestinationName") _ .ToList C# trips = context.Trips.Include("Activities") .OrderBy("it.Destination.DestinationName").ToList()

7.11.3. Add the Activities ListBox and bind it to the Trips ListBox Drag another ListBox onto the Window. You can take advantage of binding to get its data from the Trips ListBox just as you have done with the TextBoxes and ComboBoxes. The syntax is a little different because of the nature of the control. The ListBox will look similar to when it is first added to the Window.

Data binding in a ListBox is achieved with a number of attributes. DataContext performs the binding to the source, in this case lstBoxTrips. ItemsSource points to the actual items that will be used to populate the ListBox. You want the Activities EntityCollection of the selected Trip for this attribute. Next, DisplayMemberPath identifies which property of the ItemsSource will be displayed in the box. ActivityName will do the trick here. Finally, the

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 202

Return to Table of Contents

ListBox needs a little extra help synching up with the source ListBox. You need to set the IsSynchronizedWithCurrentItem to True. Here is the modified ListBox with all of the data binding attributes in place.

Don't forget that you can set some of these values in the Properties window for the control. Figure 7-16 shows the IsSynchronizedWithCurrentItem and DisplayMemberPath properties. The other binding attributes are not available in the Properties window so you'll have to type them manually. Figure 7-16. A modified view of the ListBox control's Properties window showing some of the properties that can be modified this way.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 203

Return to Table of Contents

7.11.4. Test out the app again Once you have the ListBox control configured, you should be able to see the effect of having each Trip's Activities displayed in this ListBox as you select different trips from the main ListBox. Figure 7-17 shows the application performing its newest trick. Figure 7-17. The WPF form with the Activities ListBox displaying an EntityCollection.

7.12. Editing Trips and their related data Now it's time for some editing. In the Windows Forms app, the BindingSource coordinated user actions with the entities. If a user edited data on the form, the BindingSource automatically pushed that change into the Entity, even for the related entities. Not so with WPF. While the scalar properties, such as the StartDate and EndDate properties, will get updated with no more effort than calling SaveChanges, you'll need to do a little extra coding to get the related entities to update. Add a new button to the form and change its Content property to "Save". Double click on the button to get to the Click event handler, the button's default event then add a call to SaveChanges in the event handler.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 204

Return to Table of Contents

VB Private Sub btnSave_Click _ (ByVal sender As System.Object, _ ByVal e As System.Windows.RoutedEventArgs) Handles btnSave.Click context.SaveChanges() End Sub C# private void btnSave_Click (object sender, System.Windows.RoutedEventArgs e) { context.SaveChanges(); }

Run the form and edit one of the trips changing a date and the Lodging. Close the form then run it again. When you select that trip again, you'll see that the date was updated but not the lodging. The problem isn't that it's related data, but that the ComboBox does not support updating. It is not sending the change back to the object. You'll have to do that manually using the control's SelectionChanged event. SelectionChanged is the default event so you can get to it by double-clicking on the ComboBox in the designer. Do this for the Lodging and Destination combos then add code to change the currently selected Trip's Lodging and Destination properties to the ComboBox selections. VB Private Sub cboLodging_SelectionChanged _ (ByVal sender As System.Object, _ ByVal e As System.Windows.Controls.SelectionChangedEventArgs) _ Handles cboLodging.SelectionChanged Dim selectedTrip = CType(lstBoxTrips.SelectedItem, Trip) selectedTrip.Lodging = CType(cboLodging.SelectedItem, Lodging) End Sub Private Sub cboDestination_SelectionChanged _ (ByVal sender As System.Object, _ ByVal e As System.Windows.Controls.SelectionChangedEventArgs) _ Handles cboDestination.SelectionChanged Dim selectedTrip = CType(lstBoxTrips.SelectedItem, Trip) selectedTrip.Destination = _ CType(cboDestination.SelectedItem, Destination) End Sub C# private void cboLodging_SelectionChanged (object sender, System.Windows.Controls.SelectionChangedEventArgs e) { var selectedTrip = (Trip)lstBoxTrips.SelectedItem; selectedTrip.Lodging = (Lodging)cboLodging.SelectedItem; } private void cboDestination_SelectionChanged (object sender, System.Windows.Controls.SelectionChangedEventArgs e) { var selectedTrip = (Trip)lstBoxTrips.SelectedItem; selectedTrip.Destination = (Destination)cboDestination.SelectedItem; }

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 205

Return to Table of Contents

7.12.1. What if the user changes the Destination? You might prevent destinations from being edited on existing trips, but you'll need to use that ComboBox for new trips. If the user changes the trip's destination, you won't see the change on the ListBox. WPF provides a way to sort the items of list controls with a SortedDescriptions collection. If you resort the list after the user selects a Destination from the combo, then the list will get refreshed, the new DestinationName will appear and the item will be properly sorted using the new name.

NOTE

WPF's sorting features are very different than you may be used to. You can read more about SortedDescriptions in the MSDN Documentation. Add this code at the end of the cboDestination's SelectionChanged event.

NOTE

Add System.ComponentModel to the Imports/using statements to use this feature. VB lstBoxTrips.Items.SortDescriptions.Add _ (NewSortDescription("Destination.DestinationName", _ ListSortDirection.Ascending)) lstBoxTrips.Items.SortDescriptions.Add _ (New SortDescription("StartDate", ListSortDirection.Descending)) C# lstBoxTrips.Items.SortDescriptions.Add (new SortDescription("Destination.DestinationName", ListSortDirection.Ascending)); lstBoxTrips.Items.SortDescriptions.Add (new SortDescription("StartDate", ListSortDirection.Ascending));

7.13. Adding Items to the Activities Entity Collection Next we'll add the ability to add Activities to a Trip. To do this you'll need a way to select a new Activity to add. Add a new ComboBox to the form with the name cboActivities. In the Window.Loaded event, you have already queried for the list of Activities. Now you need to bind those results to this new ComboBox. Add this binding below the binding for cboLodgings. Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 206

Return to Table of Contents

VB cboActivities.ItemsSource = activities C# cboActivities.ItemsSource = activities;

Next, the ComboBox needs to know which property to display and which to use as the value. You can set both of these in the Properties window for the ComboBox. Change SelectedValuePath to ActivityID and DisplayMemberPath to ActivityName. Unlike the other combos there are no additional bindings that need to be typed directly into the XAML. The ComboBox has a SelectionChanged event but it's not useful for reacting to a user selection. Instead, add another button to the form. We'll use that to read the selected item in the cboActivities combo and add it to the current trip's activities EntityCollection. The ListBox which shows the activities will update automatically because of its bindings. Add the following code to the new button's click event. VB Private Sub btnAddActivity_Click _ (ByVal sender As System.Object, _ ByVal e As System.Windows.RoutedEventArgs) _ Handles btnAddActivity.Click Dim selectedActivity = CType(cboActivities.SelectedItem, Activity) If Not selectedActivity Is Nothing Then Dim selectedTrip = CType(lstBoxTrips.SelectedItem, Trip) If Not selectedTrip Is Nothing Then selectedTrip.Activities.Add(selectedActivity) End If End If End Sub C# private void btnAddActivity_Click (object sender, System.Windows.RoutedEventArgs e) { Activity selectedActivity = (Activity)cboActivities.SelectedItem; if (selectedActivity != null) { var selectedTrip = (Trip)lstBoxTrips.SelectedItem; if (selectedTrip != null) { selectedTrip.Activities.Add(selectedActivity); } } }

This code ensures that an Activity is selected and a Trip is selected before it tries to do the main task. Notice how the new Activity is added to the Trip's Activities collection. You will likely use the EntityCollection. Add method quite a lot in your Entity Framework based applications. Chapter [X], Relationships and Associations drills into this functionality in detail.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 207

Return to Table of Contents

7.13.1. Test out adding activities Run the app, select a trip and add some activities. You'll see the Activities ListBox react. You can save the changes with your existing Save method. Note that since the data is not refreshed, again, you'll want to stop and start the application for proof that the change was saved.

7.14. The Last Task! Add new Trips to the Catalog Adding new trips will take a bit more code to implement. Not only will you need to set some defaults on the new trip entity, but there are a few tricks that you'll have to use in order to make the User Interface flow properly. Start by adding a new button to the form that will be the user's "New Trip" button. That's all that you need to do in the UI. In the button's Click event you'll create a new trip and set some defaults.

7.14.1. A few WPF tricks to make the ListBox work more interactively with its Trips Before doing this, there are two changes you'll need to make that are related to WPF's data binding and not specifically about entities. In the WindowsForm, you had a BindingSource to coordinate between the controls and the data. There's no such control in WPF, however there's another mechanism called the ObservableCollection. Without getting too sidetracked, if you use an ObservableCollection of trips as the source for the Trip ListBox control, then as you add and remove items from this collection, the ListBox will respond by adding or removing the items from the display. It's worth the effort to use this rather than a List so that you won't have to do the extra work of stuffing how to get your new trip into the ListBox. To pull this off you'll need a new variable that is scoped to the whole Window. Add this to the Window's declarations. We'll instantiate it in the declaration so that it's ready to use in the Window.Loaded event.

NOTE

Add the Collections.ObjectModel namespace to the Imports/using statements to use this feature. VB Private ObservableTrips As New ObservableCollection(Of Trip)

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 208

Return to Table of Contents

C# private ObservableTrips = new ObservableCollection();

In the Window.Loaded event, after the trips query has been executed, transfer the Trip results into the new collection. Then change the ItemsSource of the Trips ListBox to this new collection. VB For Each t In trips ObservableTrips.Add(t) Next lstBoxTrips.ItemsSource = ObservableTrips C# foreach (var t in trips) { ObservableTrips.Add(t); } lstBoxTrips.ItemsSource = ObservableTrips;

Now when you add new trips to the collection they will automatically pop into the ListBox. But they'll be at the bottom and remain there until you run the application again. That's no good. You can get the ListBox to sort on the DestinationNames and StartDates using this WPF code which is very different from what you might be used to with WinForms or ASP.NET apps. You can copy the sorting code from the Destination ComboBox's SelectionChanged event into the Window.Loaded event to benefit from the sorting early on. This way, if you add a new Trip before you hit the other location where the sort is applied, the new trip will drop into the correct position in the ListBox. With the ListBox controlling the sort, you can remove the OrderBy method in the Trips query.

NOTE

You'll still need the sorting code in the ComboBox to trigger the refresh. There may be a better way to trigger a refresh in the ListBox than calling adding the SortDescription again. But this little trick will do for now.

7.14.2. Adding a new trip With that functionality in place you can now add the trips and have the form respond in an expected manner. The Click event of the NewTrip button will add a new trip, set some default values and get the trip into the ListBox's Items.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 209

Return to Table of Contents

VB Private Sub btnNewTrip_Click _ (ByVal sender As System.Object, _ ByVal e As System.Windows.RoutedEventArgs) Handles btnNewTrip.Click 'create a new Trip Dim newtrip = New newtrip.StartDate newtrip.EndDate =

object with default date values Trip = Today Today

'add a default destination. Sorting will fail if Destination is null newtrip.Destination = destinations(0) 'add the trip to the context so that it's changes will get tracked context.AddToTrips(newtrip) 'add the new trip to the bound collection ObservableTrips.Add(newtrip) 'select the new trip so that the bound controls will be tied to it lstBoxTrips.SelectedItem = newtrip End Sub C# private void btnNewTrip_Click (object sender, System.Windows.RoutedEventArgs e) { \\create a new Trip() object with default System.DateTime values var newtrip = new Trip(); newtrip.StartDate = System.DateTime.Today; newtrip.EndDate = System.DateTime.Today; \\add a default destination. Sorting will fail if Destination == @null newtrip.Destination = destinations(0); \\add the trip to the context so that it's changes will get tracked; context.AddToTrips(newtrip); \\add the new trip() to the bound collection ObservableTrips.Add(newtrip); \\select the new trip() so that the bound controls will be tied to it lstBoxTrips.SelectedItem = newtrip; }

7.14.3. Validate the new trips before saving There's one last bit of code you will want to consider using, though you can certainly skip it for this demo – Validation code for the new trip. Here's a short method you can call prior to SavingChanges to prevent your demo from blowing up if you get click-happy. It just checks to make sure that any new trips have a destination and valid start and end dates. If it returns False, then display some type of message and don't call SaveChanges. VB Private Function validateNewTrips() As Boolean Dim newtrips = From t In ObservableTrips _ .Where(Function(t) t.TripID = 0) For Each Trip In newtrips If Trip.Lodging Is Nothing Then Return False ElseIf Trip.StartDate < Today Then Return False ElseIf Trip.EndDate < Trip.StartDate Then Return False Else

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 210

Return to Table of Contents

Return True End If Next End Function

7.14.4. Test the final version of the WPF demo Run the demo again and check out the new features. When you add a new trip, watch how smoothly the bound Trip ListBox displays that at the top of the ListBox. When you change the default destination, the trip will reappear alphabetically sorted in the ListBox, but still selected. Add some Activities to the new trip. Save your changes and restart the app to prove to yourself that it all really worked. Figure 7-18. The final WPF Form with all of its features in place

7.15. Chapter Summary Entity Framework has a number of levels of entry. In this chapter you got a chance to apply much of what you have learned in the previous chapters in creating two starter client side applications. The Windows Forms app leaned heavily on drag and drop data binding while the WPF application let you get your hands a little more dirty interacting with the entities in code. The apps went beyond the typical Hello World applications and gave you an opportunity to learn some of the nuances of data binding with Entity Objects. At the same time you Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 211

Return to Table of Contents

learned how to perform some good data binding tricks in Windows Forms and WP that will make life with entities a little easier. In the next chapter you are going to dive into a little more theory as you go much deeper under the covers of how Object Services manages the entity objects.

Chapter 8. Object Services Most of the work that you will do in Entity Framework will involve the objects that are based on the entities in our EDM. The Object Services API is the part of the framework that creates and manages these objects. While you have worked with Object Services in much of the code you have already written and you have touched on a variety of its topics along the way, you haven't had a chance to see the big picture. There are a lot of tools in the API that you can access directly to take charge of your entity objects.

Licensed by Dave Olsen

This chapter will be devoted to your gaining a better understanding of the Object Services API; of what it is responsible for, what it does under the covers and some of the ways you can take advantage of it.

8.1. Where Do Object Services Fit into the Framework? Object Services are at the top of the food chain in the Entity Framework. The namespace for this API is System.Data.Objects and it provides all of the necessary functionality to generate and interact with the objects that are shaped by the conceptual layer and populated from a data store. As shown in Figure 8-1, it is the Object Services that initially process your LINQ to Entities and ObjectQuery queries as well as materialize the query results into objects. Figure 8-1. Object Services sit on top of the Entity Framework stack, where they provide .NET objects for you to work within your application.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 212

Return to Table of Contents

The core functionality of Object Services can be divided into seven areas: 1. 2. 3. 4. 5. 6. 7.

Query processing Object materialization Object Management Object Relationship Management Object State Management DML Command Processing Additional features

8.2. Query Processing In the past few chapters you have seen that there are quite a few ways to create queries in the Entity Framework. Object Services is used for all of the query methods except EntityClient which uses a lower level API. Object Services sits on top of Entity Client and leverages its functionality on your behalf. At a high level, Query Processing in the Entity Framework involves translating the LINQ or Entity SQL queries into queries that can be processed by the data store. At a lower level, it first parses your query into a Command Tree of LINQ or Entity SQL Query operators and functions combined with the necessary entities and properties of your model. The Command Tree is a format that the various providers which have been designed to work

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 213

Return to Table of Contents

with Entity Framework will be expecting. Next, the Entity Data Model and the provider API (Oracle, SQL Server, MYSQL, etc.), are used to transform this tree into a new expression tree made up of the provider's operators and functions and the database's tables and columns. This tree is finally passed to the database.

Expression Trees & Command Trees {define here...}

8.2.1. From Query to Command Tree to SQL LINQ to Entities leverages the LINQ parser to get begin the query processing while ObjectQueries use a different parser. After each has gone through their first transition, they follow the same path. Let's take a look at how each of the queries is turned into the eventual store command.

NOTE

Store Command or Native Command refers to the command that is used by the data store, for example a TSQL command for SQL Server.

8.2.1.1. LINQ to Entities Query to a Command Tree LINQ starts its journey in the LINQ APIs and is then passed to the Object Services API. When you create a LINQ to Entities query, you are using syntax that is built into Visual Basic and C# that has enhancements added by the Entity Framework. LINQ converts this query into a LINQ Expression Tree. Expression Trees are a way of deconstructing queries into their common operators and functions. The LINQ Expression tree is then passed to Object Services which converts it to a Command Tree.

8.2.1.2. Entity SQL & Query Builder Methods to a Command Tree The ObjectQuery class and the Query Builder Methods which you've been using are part of Object Services. When building a query with ObjectQuery, you write an Entity SQL string to express the query. If you use Query Builder Methods, those methods will build an Entity SQL Expression and an ObjectQuery for you. The ObjectQuery then passes the Entity SQL string to Entity Client's parser and this parser creates a Command Tree. Whether a query began as LINQ to Entities or an ObjectQuery with Entity SQL, the Command Trees are the same. From this point on, both types of queries follow the same processing path. Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 214

Return to Table of Contents

NOTE

For the sake of comparison, an when you query using Entity Client, it's Entity SQL expression is also parsed into a Command Tree and meets up with the others at this stage of the process.

8.2.1.3. How Entity Client turns Command Trees into Store Commands The newly created Command Tree is still expressed in terms of the Entities in the conceptual layer of the model. Next, the processor uses the EDM mappings to transform the terms of the Command Tree into the tables, columns and other objects of the database. This process might run through the command tree a number of times to simplify the demands made in the query before it's possible to come up with equivalent of the database's tables and columns. Once this new version of the tree has been created, it is sent to the Store Provider (e.g., SqlClient) which will know how to convert a Command Tree into its native command text. Entity Framework Provider writers use the common schema of a Command Tree to create their functionality for generating SQL from the Command Tree. For example, the SqlClient provider transforms the tree into TSQL that can be executed by SQL Server; an Oracle provider will transform the tree into a proper PL/SQL command. Figure 8-2 shows the steps that these queries go through to get to the Data Store. Figure 8-2. Figure Caption Text Goes Here

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 215

Return to Table of Contents

8.2.2. A Better Understanding of Query Builder Methods Writing Entity SQL is not always simple. While familiar to those who write store commands already, it is different enough that it will probably take some time before the syntax rolls naturally from your fingertips. Query Builder methods can be quite useful as the methods are discoverable through Intellisense and take away some of the pain of remembering the exact syntax. In Chapter 4 you built a variety of queries using the CreateQuery method with an Entity SQL expression as its parameter. You also used Query Builder Methods. Example 8-1 and Example 8-2 are refreshers showing these side by side. Example 8-1. CreateQuery with Entity SQL

VB Dim qStr = "SELECT VALUE c " & _ "FROM PEF.Contacts AS c " & _ "WHERE c.FirstName='Robert'" Dim contacts = context.CreateQuery(Of Contact)(qStr)

C# var queryStr = "SELECT VALUE c " + "FROM PEF.Contacts AS c " + "WHERE c.FirstName='Robert'"; var contacts = context.CreateQuery(queryStr);

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 216

Return to Table of Contents

Example 8-2. Query Builder Method with Entity SQL parameters

VB Dim contacts = context.Contacts _ .Where("it.FirstName = 'Robert'")

C# var contacts = context.Contacts .Where("it.FirstName = 'Robert'")

Both sets of code define the same ObjectQuery which searches for contacts whose first name is Robert. Neither will actually return results until something forces the query to be executed. The Query Builder methods may still require writing some of the expression, such as the Where predicate "it.FirstName='Robert'" in Example 8-2, but it's still a great deal easier.

8.2.2.1. Query builder methods and EntitySets Query Builder methods are methods of ObjectQuery. How is it then, that these methods are available from context.Contacts? The classes generated from the model reveal the answer to this question. The above queries are based on the first model you built and used in Chapter 3 and Chapter 4. context is a variable that represents the ObjectContext "PEF", the wrapper class which serves up the EntitySets of the various classes in the model. Recall that in Chapter 3 this was called ProgrammingEFDB1Entities, but in Chapter 4 we simplified this name to PEF. Example 8-3 shows the declaration of this class in the classes generated from the model. Example 8-3. Declaration of the ObjectContext

VB Partial Public Class PEF Inherits Global.System.Data.Objects.ObjectContext

C# public partial class PEF : global::System.Data.Objects.ObjectContext

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 217

Return to Table of Contents

This class has a property for each of the EntitySets, for example Contacts. Each of these properties returns an ObjectQuery(Of T)/ObjectQuery of the entity type it wraps. The Contacts property returns an ObjectQuery of Contact entities as shown in Example 8-4. Example 8-4. The ObjectContext.Contacts property

VB _ Public ReadOnly Property Contacts() As _ Global.System.Data.Objects.ObjectQuery(Of Contact) Get If (Me._Contacts Is Nothing) Then Me._Contacts = MyBase.CreateQuery(Of Contact)("[Contacts]") End If Return Me._Contacts End Get End Property

C# public global::System.Data.Objects.ObjectQuery Contacts { get { if ((this._Contacts == null)) { this._Contacts = base.CreateQuery("[Contacts]"); } return this._Contacts; } }

Because the property returns an ObjectQuery, it has all of the methods and properties of an ObjectQuery, including the Query Builder Methods — Select, Where, GroupBy, etc.

8.2.2.2. From Query Builder to Entity SQL ObjectQuery uses the Query Builder methods and any expressions such as what is contained in a Where clause to build an Entity SQL expression. The end result is the same as if you had explicitly created a QueryObject and types in the Entity SQL yourself. The expression is then used to create a QueryObject in the same way that the CreateQuery method does.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 218

Return to Table of Contents

How Do You Tell the Difference Between LINQ Methods and Query Builder Methods? LINQ's method syntax looks very similar to the Query Builder methods except for one big difference—the parameters. The parameters of a LINQ method are lambda expressions while the parameters of the Query Builder methods are Entity SQL string expressions. There are a number of methods with the same name: Where, OrderBy, Select and others. The compiler uses the parameters to determine which path to go down much in the same way the .NET compiler handles overloaded methods anywhere else.

8.2.2.3. Combining LINQ methods and Query Builder methods Query Builder methods return ObjectQueries and you can use a LINQ to Entities method on an ObjectQuery. Therefore it's possible to compose a query such as the one in Example 8-5. Example 8-5. Query Builder method followed by LINQ method context.Contacts.Where("it.FirstName='Robert'").Take(10)

The first part, context.Contacts.Where("it.FirstName='Robert'"), returns an ObjectQuery. Then LINQ's Take method is appended to that. The resulting query will be a LINQ to Entities query. You can't go the other way though, adding Query Builder methods after a LINQ method. context.Contacts.Take(10) returns a System.LINQ.IQueryable. Query Builder methods can only be used on ObjectQueries, so you cannot append a Query Builder method to this IQueryable. You would have to first cast the LINQ query to an ObjectQuery and then append the method. There are actually a number of scenarios where casting a LINQ to Entities query to ObjectQuery is beneficial and you'll see these as you move forward through this chapter.

8.2.3. Breaking Apart the ObjectQuery You have already seen some of the members of ObjectQuery such as the Query Builder Methods and Include. There are more methods and properties which will help you better understand the role of ObjectQuery. Here are some that you can see when inspecting an ObjectQuery in the debugger.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 219

Return to Table of Contents

Figure 8-3 shows an ObjectQuery in debug mode with its properties as well as a way to access the results. Looking at a LINQ to Entities query in the debugger ( Figure 8-4) shows that LINQ to Entities exposes the results directly but also contains an ObjectQuery. Figure 8-3. An ObjectQuery called "contacts" in the debugger shows the various properties of ObjectQuery.

Figure 8-4. A LINQ to Entities query in the debugger shows that the LINQ to Entities query contains an ObjectQuery.

If you want to get to ObjectQuery properties and methods from a LINQ to Entities query, you can cast the LINQ to Entities query to ObjectQuery.

8.2.3.1. The ToTraceString method One of the very helpful ObjectQuery methods is ToTraceString which displays the native store command that will be created from your query. Figure 8-5 shows some code that calls ToTraceString and the value returned by the method at runtime. Figure 8-5. Viewing the native command that will be generated from an ObjectQuery using the ToTraceString method while debugging.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 220

Return to Table of Contents

Example 8-6 demonstrates casting a LINQ to Entities query to an ObjectQuery in order to call the ToTraceString method. Example 8-6. Cast a LINQ to Entities query to use ObjectQuery methods such as ToTraceString

VB Dim contacts = From c In context.Contacts Where c.FirstName = "Robert" Dim str = CType(contacts, Objects.ObjectQuery).ToTraceString

C# var contacts = from c in context.Contacts where c.FirstName == "Robert" select c; var str = ((Objects.ObjectQuery)contacts).ToTraceString();

8.2.3.2. ObjectQuery's CommandText and Parameters As with ADO.NET, the CommandText refers to the query string being passed in for execution. Because of the different ways to build queries with Entity Framework, the CommandText is represented in a variety of ways.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 221

Return to Table of Contents

Table 8-1. CommandText values of various types of queries

ObjectQuery ObjectQuery with Entity SQL Query Builder

LINQ to Entities

Query Context.Contacts context.CreateQuery(Of Contact) ("SELECT VALUE c FROM PEF.Contacts AS c WHERE c.FirstName='Robert'") context.Contacts .Where("it.FirstName = 'Robert'") .OrderBy("it.LastName") From c In context.Contacts Where c.FirstName = "Robert"

ObjectQuery.CommandText [Contacts] SELECT VALUE c FROM PEF.Contacts AS c WHERE c.FirstName='Robert' SELECT VALUE it FROM (SELECT VALUE it FROM ([Contacts]) AS it WHERE it.FirstName = 'Robert') AS it ORDER BY it.LastName (empty)

8.2.3.3. ObjectQuery.Parameters In Chapter 4 you saw how to build a parameterized query. Any parameters that you created then will be listed in the ObjectQuery's Parameters property.

8.2.3.3.1. ObjectQuery.Context The Context property refers back to the instantiated ObjectContext which the ObjectQuery is being run from The ObjectContext not only coordinates the execution of queries and provides the mechanism for SavingChanges back to the data store, but it plays a much bigger role as the manager of objects in memory.

8.2.4. Query Execution with ToList or ToArray So far the query has been defined, but no data retrieval has actually occurred. Query Execution is when the Entity Framework retrieves the data from the store. Queries can be executed implicitly or explicitly. In previous chapters you have enumerated over the results of a query (using for each). Enumerating over a query will force a query to execute implicitly. You don't need to specifically say "go get the data". The fact that you are attempting to work with the query results will cause EF to do that for you. Another way to force execution is to append the ToList or ToArray LINQ methods to a Query. Example 8-7 shows appending ToList to the CreateQuery method to execute the query immediately and return a List of Contact entities. Example 8-7. Execute a query with ToList

VB Dim contacts =

context.CreateQuery(Of Contact)(queryStr).ToList()

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 222

Return to Table of Contents

C# var c2 = context.CreateQuery(queryStr).ToList();

NOTE

A big difference between using ToList or ToArray rather than enumerating is that these methods will force the complete results to be returned all at once. When enumerating, depending on what you are doing with each result as you get to it, it may take a while before you get to the end. Until that time, the database connection will remain opened.

8.2.5. Query Execution with the Execute Method QueryObject has an Execute method which also forces execution, but it requires a parameter to define Merge Options for the resulting objects. VB Dim contacts = context.Contacts.Execute(MergeOption.AppendOnly)

C# var contacts = context.Contacts.Execute(MergeOption.AppendOnly);

There are four merge options which impact how newly returned objects impact objects that may already exist in memory. MergeOptions are also a property of the ObjectQuery so that you can set the value directly even when not using the Execute Method. AppendOnly is the default and when you don't set the option directly when executing other queries, that's what will be used. However, with Execute, you must set this parameter, even if you just want the AppendOnly default. You've already used Execute in the previous chapter for the Windows Forms data binding example. Execute does not return an ObjectQuery but a type called ObjectResult. An ObjectQuery contains all of the metadata about the query itself, the query expression, the connection information, and more as well as any results (after the query has been executed). When Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 223

Return to Table of Contents

you use the Execute method, however, you have only the results, not the metadata. There are benefits to using Execute in some scenarios but in others, its limitations, such as the fact that you can only enumerate over ObjectResults once, might be a problem. Because MergeOptions impact what happens with the returned data, its purpose will make more sense after some other topics have been discussed. We'll return to Merge Options in more detail later in the chapter.

8.2.6. ObjectContext.Connection By default, the ObjectContext will use the connection string defined in the application's config file which has the same name as the name of the context's EntityContainer. Fr example, when the EntityContainer name was BAEntities, Object Services will search for a connection string named BreakAwayEntities in the config file. If no matching connection string is found and no override is provided, an exception will be thrown at runtime. The exception says "The specified named connection is either not found in the configuration, not intended to be used with the EntityClient provider, or not valid." There are a number of ways to override the default behavior. One way to override the default is to supply a different connection string name in the constructor of the ObjectContext. This string needs to be available in the config file as well. Example 8-8 uses the connection string named "connString" to create an ObjectContext. Example 8-8. Specifying which EntityConnection string to use for a context

VB Dim context=new PEF("Name=connString")

C# var context = new PEF("Name=connString");

NOTE

Note that you can't just use the connection string name but you need to add "Name=" as part of the parameter. Another way to override the default is to supply an EntityConnection object instead. This would be the same EntityConnection that is used with the EntityClient provider. By

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 224

Return to Table of Contents

creating an explicit EntityConnection you can manipulate that EntityConnection prior to instantiating a context with it. Example 8-9 shows creating the EntityConnection, but not doing anything special with it. You will learn a lot more about manipulating EntityConnections in Chapter 13. Example 8-9. Explicitly creating a new EntityConnection to use with a context.

VB Dim econn = New EntityConnection("name=connString") Dim context = New PEF(econn)

C# var econn = new EntityConnection("name=connString"); var context = new PEF(econn);

8.2.6.1. Why does the context need the EntityConnection? The EntityConnection gives ObjectContext two important pieces of information. The metadata, which points to the CSDL, SSDL and MSL files, provides the context with the location of these files. They can be embedded into an assembly or sitting somewhere in the file system. The context needs access to the metadata files in order to begin the process of transforming the query into the store command. ObjectContext will pass the database connection string onto the EntityClient layer so it will be able to connect to the database and execute the command. The last element of an EntityConnection string is the name of the data provider, e.g., System.Data.SqlClient. This tells Entity Framework which data provider to send the command tree to for part of the query processing.

8.2.7. EntityClient Handles the Command Execution So what's next? You've got your ObjectQuery all set. You know that the ObjectQuery will do all of the work to create a Command Tree. Somehow, the Command Tree gets handed off to the EntityClient Provider along with the database connection string provided by the ObjectContext. If you dig into the Entity Framework assemblies using reflector, you will find that the ObjectContext calls on EntityClient to do the job of creating the connection and executing the command on the data store. As you saw with the EntityClient queries in Chapter 4, EntityClient returns an EntityDataReader, not objects.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 225

Return to Table of Contents

8.3. Object Materialization After EntityClient retrieves the EntityDataReader it passes that back up the stack to Object Services, which transforms, or materializes, the results into entity objects. The data in EntityDataReader is already in the terms of the Conceptual Layer so it's just a matter of those contents being cast to objects. If the query used a projection and there is no matching entity, then as you saw in many of the queries you wrote earlier, the results are materialized into DbDataRecords instead of entity objects. Figure 8-6 demonstrates the path that a query takes from the Command Tree to the database and then back to Object Services to be materialized into objects. Figure 8-6. The EntityClient provides the command execution functions for an ObjectQuery. The query results are sent back to Object Services to be materialized into Objects.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 226

Return to Table of Contents

8.4. Object Management The ObjectContext is the core class in Object Services. It performs a large variety of functions 1. It provides connection and metadata information needed to compose and execute queries as well as to persist data to the data store. 2. It acts as a caching container for objects in memory, whether they have been retrieved from the database, created programmatically or brought from another ObjectContext. 3. It enables binary and xml serialization of Entity Objects. This can be performed directly by your code or implicitly by other .NET features that call for serialized data. 4. It maintains the state information of all of the objects that it is managing as well as retaining the original and current values of all of the objects. 5. It provides relationship information so that graphs can be created from related objects that it is managing. You have actually seen the ObjectContext perform all of these functions in the code you have written in the previous chapters. Now it's time to dig a little deeper.

8.4.1. Object Context Is a Cache for In-Memory Objects When objects are returned from queries, the ObjectContext creates pointers to each entity, in effect caching references to these entities. The ObjectContext not only keeps track of all of these entities but it also keeps track of other information about those entities including their state, their original and current values and their relationships to one another.

An ObjectContext by Any Other Name There are a number of ways to refer to the ObjectContext or to talk about objects that are being managed by the context. The ObjectContext=Context=Cache=Object Cache Entity is Managed by the context=Entity is being Change Tracked = Entity is Cached= Entity is Attached to the ObjectContext

8.4.1.1. Objects are not required to be in the ObjectContext cache Objects can be in memory without being in managed by the ObjectContext. That means that although the object instance exists, the ObjectContext is not aware of the object. There are a number of ways to have an EntityObject in application memory that is not being tracked by the context.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 227

Return to Table of Contents

Explicitly instruct the ObjectQuery to return objects without attaching them to the cache. This is done with the ObjectQuery.MergeOption. • Explicitly detach an object from the ObjectContext using the ObjectContext.Detach method. • Create a new object in memory. •

Unless or until you explicitly Attach or Add the object to the ObjectContext or to an object that is already in the cache (e.g., adding a Reservation to a Customer's Reservation EntityCollection property or adding a Customer as a Reservation's CustomerReference), it is not part of the cache. • Deserialize entities that were serialized. While the act of serializing an entity or entities does not detach entities from their ObjectContext, the entities that are in the serialized package will not be attached to an ObjectContext when they are deserialized. The EntityState of an object that is not in the cache is Detached. Chapter 12 (Relationships and Associations) and Chapter 14 (Take Control of Objects with ObjectStateManager and Metadata Workspace) will provide much more insight into controlling the ObjectContext and that caching has on entities' relationships and change tracking.

8.4.2. Entity Objects When objects are returned from queries they are attached to the ObjectContext by default. The only responsibility of an Entity Object is to know what its current state is; that is, to know the current values of its properties. The properties of an entity class are the scalar and navigation properties which define the schema of that entity. For example, the BreakAway Contact class has only the following properties: ContactID, FirstName, LastName, AddDate, ModifiedDate, Title, Customer, Addresses and Lodging. These are the same properties that are in the entity in the model. You can look into the classes to see what the code looks like. For a bit of it, here is the Visual Basic code related to the scalar property, FirstName. _ Public Property FirstName() As String Get Return Me._FirstName End Get Set Me.OnFirstNameChanging(value) Me.ReportPropertyChanging("FirstName") Me._FirstName = Global.System.Data.Objects.DataClasses. _

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 228

Return to Table of Contents

StructuralObject.SetValidValue(value, false, 50) Me.ReportPropertyChanged("FirstName") Me.OnFirstNameChanged End Set End Property Private _FirstName As String Partial Private Sub OnFirstNameChanging(ByVal value As String) End Sub Partial Private Sub OnFirstNameChanged() End Sub

There are two events that were created by the code generator for the FirstName property —OnFirstNameChanged and OnFirstNameChanging. These partial methods are defined in the class to give us the ability to add code to handle these events. You will learn how to extend the classes event handling and other code in the next chapter, Customizing Entities. Each entity class also has a single method whose name begins with "Create". These methods allow you to create a new instance of that class. The parameters of the Create methods take values for each non-nullable scalar property in the class. For the Contact class, you may notice that the Title parameter is not being used. That's because it is a nullable property. VB Public Shared Function CreateContact(ByVal contactID As Integer, _ ByVal firstName As String, ByVal lastName As String, _ ByVal addDate As Date, ByVal modifiedDate As Date) As Contact Dim contact As Contact = New Contact contact.ContactID = contactID contact.FirstName = firstName contact.LastName = lastName contact.AddDate = addDate contact.ModifiedDate = modifiedDate Return contact End Function

C# public static Contact CreateContact(int contactID, string firstName, string lastName, global::System.DateTime addDate, global::System.DateTime modifiedDate) { Contact contact = new Contact(); contact.ContactID = contactID; contact.FirstName = firstName; contact.LastName = lastName; contact.AddDate = addDate; contact.ModifiedDate = modifiedDate; return contact; }

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 229

Return to Table of Contents

Once you have used this function to create a new contact, you can add additional properties in code. You won't find much more when looking in the classes generated from the model. The entity class itself has no properties for keeping track of its state changes. It only maintains the current values of its properties.

8.4.3. Entity Keys and EntityState The Entity does, however, inherit from EntityObject, and therefore exposes two additional properties that come from EntityObject: EntityKey and EntityState. EntityKey is a critical class for keeping track of individual entities. It contains the entity's ID, which could be from a single property, such as ContactID, or could be a composite key that depends on a number of the entity's properties. Figure 8-7 shows an EntityKey for a BreakAway Contact. It says that this entity belongs to the container "BAEntities", to the EntitySet "Contacts" and that it's key property is comprised of only one property, ContactID whose value is 1. The ObjectContext reads the EntityKey information to perform many of its functions. Some examples are when the context merges objects, locates entities in the cache and also for the purpose of creating EntityReference values. The type information is not included in the EntityKey. Instead, the EntitySetName indicates which EntitySet the object with this key belongs to. This little class is one of the most important classes in the Entity Framework. It acts as an object's passport throughout the application's runtime. Figure 8-7. An object's EntityKey includes critical identity information for each object.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 230

Return to Table of Contents

8.4.3.1. The EntityState enums The EntityState property of an object's EntityKey identifies if the entity is: Added An entity that was instantiated at runtime and added to the context. When SaveChanges is called, Object Services will create an Insert command for this entity. Deleted An entity that is being managed by the cache and has been marked for deletion. When SaveChanges is called, Object services will create a Delete command for this entity. Detached The entity is not being tracked by the ObjectContext. Modified The entity has been changed since it was attached to the context. Unchanged No changes have been made to the entity since it was attached to the context.

8.4.3.2. If the entity is Modified, where are the details about the changes? So far you have looked closely at the EntityObject and its EntityKey, but there is still no sign of the entity's original values and which ones have been changed. These details are maintained by the Object Context. You'll see how this works in the upcoming section called State Management.

8.4.4. Merging Results into the Cache By default, any time the ObjectContext performs a query, if any of the returned objects already exist in the cache, the newly returned copies of those objects are ignored. The EntityKeys are instrumental in enabling this to happen. The EntityKeys of the objects returned from a query are checked and if an object with the same EntityKey (within the same EntityContainer, e.g. Contacts) already exists in the cache, the existing object is left untouched. You can control this using an ObjectQuery property called MergeOption. The four possibilities for MergeOption are:

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 231

Return to Table of Contents

AppendOnly (default) Only add new entities to the cache. Existing entities are not modified. OverwriteChanges Replace the current values of existing entities with values coming from the store. PreserveChanges Replace original values of existing entities with values coming from the store. The current values are untouched and therefore any changes made by the user will remain intact. This will make more sense after the discussion of State Management. NoTracking Objects returned by the query will not have their changes tracked and will not be involved in SaveChanges. Again, this will make more sense after the discussion of State Management. There are two ways to define MergeOptions. The first is using the MergeOption method of ObjectQuery: VB Dim contacts = context.CreateQuery(Of Contact)(queryString) contacts.MergeOption = MergeOption.PreserveChanges

The second is as a parameter of the QueryObject.Execute. Although AppendOnly is the default, with Execute you must explicitly include the parameter, even if you want to use the default. VB Dim contacts = context.CreateQuery(Of Contact)(queryString) contacts.Execute(MergeOption.OverwriteChanges)

Remember that you can cast a LINQ to Entities query to an ObjectQuery and use ObjectQuery methods, as you did with ToTraceString earlier in this chapter.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 232

Return to Table of Contents

8.5. State Management and ObjectStateEntry The ObjectContext manages the state information for each of its objects. It maintains a collection of ObjectStateEntry classes, one for each entity and relationship in its cache. For now, we'll focus on the objects, not the relationships. You can retrieve an ObjectStateEntry by passing an EntityKey to the ObjectContext.ObjectStateManager.GetObjectStateEntry method.

NOTE

GetObjectStateEntry has a sibling method called TryGetObjectStateEntry. In this chapter, you will get a high level look at the ObjectStateManager and ObjectStateEntry classes. Chapter 14, ObjectStateManager and MetadataWorkspace will dig much more deeply into these classes. Debugging the ObjectStateEntry won't give you much insight into the object, but you can see that this ObjectStateEntry in Figure 8-8 is for the Contact whose ContactID is 6. Figure 8-8. By default, debugging the ObjectStateEntry for a Customer in the object cache doesn't provide much insight.

The more interesting information is returned from some of the methods of the entry, CurrentValues and Original Value. These methods return an array of the values for each scalar property. You would need to know the index position of the property you are seeking, for example, the original value of FirstName can be returned by calling contactEntry.OriginalValues(3) in VB or contactEntry.OriginalValues[3] in C#. There is also metadata available from the entry so it is possible to find values by using the property names. This will take a little bit more effort and you'll learn about navigating around these entries in Chapter 14, ObjectStateManager and MetadataWorkspace.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 233

Return to Table of Contents

Figure 8-9 and Figure 8-10 use a custom utility which you'll learn how to write in Chapter 14, to show the ObjectStateEntry information for an entity before and after some changes have been made Figure 8-9. This viewer, which you'll learn how to write in Chapter 14, inspects and displays information from an unchanged Entity's ObjectStateEntry.

Figure 8-10. The same viewer shown in Figure 8-9 shows the changes made to the entity as defined in its ObjectStateEntry.

What is most important to understand right now is that CurrentValues and the OriginalValues are tracked, but it is the ObjectContext that maintains this information.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 234

Return to Table of Contents

8.5.1. Change Tracking The way that the ObjectContext knows about the state of an object is through Change Tracking. Every entity implements the IEntityWithChangeTracker interface. Recall that the PropertyChanging and PropertyChanged events in the model classes represent part of Change Tracking functionality. When an object's property is changed, the IEntityWithChangeTracker interface reports this change to the designated ChangeTracker, i.e., the current ObjectContext, which updates the appropriate value of that object's ObjectStateEntry. In order for this to work, the Object inherits internal functions from IEntityWithChangeTracker. This interface does have two public members—the SetChangeTracker and RemoveChangeTracker methods—that allow you to identify which ObjectContext is responsible for the change tracking. These methods are used internally and although they may seem tempting in some scenarios, you will almost always be better off not using them directly.

8.6. Relationship Management While objects know how to traverse from one to another, it is the ObjectContext that binds related objects together. This may not be evident, even if you perform a query that explicitly retrieves a graph such as context.Customers.Include("Reservations.Trip") .Include("Reservations.Payments")

The resulting graph is depicted in Figure 8-11. Figure 8-11. A Customer graph including Reservations and other related objects.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 235

Return to Table of Contents

In fact, while it may look like your query is shaping the returned data, the object graph is shaped by the ObjectContext after the objects have been materialized and attached to the context. The ObjectContext's ability to identify and implicitly join related entities is referred to as Relationship Span.

NOTE

This chapter aims at giving you a high level understanding of Relationships. However, Relationships and Associations are a very interesting topic and will be covered much more thoroughly in Chapter 14. You can explicitly combine related entities in code. Here's an example of code which creates a new Reservation object than adds it to a Customer's Reservations property. The Reservations property is an EntityCollection, so this code adds the new Reservation not to the Customer, but to the collection. VB Dim res = Reservation.CreateReservation(0, New Date(2008, 10, 1)) c.Reservations.Add(res)

C# var res = Reservation.CreateReservation(0, new DateTime(2008, 10, 1)); c.Reservations.Add(res);

However if you were to perform queries that returned Customers and Reservations separately, the ObjectContext would identify those which are related and make it possible for you to traverse through Customer.Reservations or Reservation.Customer with no effort. The ObjectContext takes care of that for you and it is referred to as relationship span. When poking around the entity classes, you may have noticed that the EntityCollection properties, such as Addresses and Reservations were read-only. Because of the way ObjectContext works, you can't attach an EntityCollection directly to an Entity. In other words if you had a collection of Addresses that belong to a contact, you can't just call Contact.Addresses=myAddressCollection. Instead, you must add the address entities to the Contact.Addresses entity collection one at a time using context.Addresses.Add(myAddress). There is also an Attach method for connecting related entities. Chapter 14 is devoted to the ins and outs of relationships in the Entity Framework. Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 236

Return to Table of Contents

Object Graphs? An object graph refers to a set of related objects that are seen as a whole unit. An Entity Object Graph may look like a single unit when you are coding against it, but in fact, it is a collection of objects and relationships. The most tangible way to view a graph is to serialize it to XML, where the related objects are represented hierarchically. Each object contains the objects which it is related to.[1] [1]

This still isn't' working for me. I want it in the book because there was a time when I did not understand the term and I don't want to assume that every reader already know what it means. Is there a better/simpler way to explain this in layman's terms?

8.6.1. Attaching and Detaching Objects from the ObjectContext Attaching and Detaching have been mentioned a number of times in this chapter. Objects whose changes and relationships are being managed by the context are considered to be Attached. EntityObject instances that are in memory but not being managed by the context are considered Detached and even have their EntityState value set to "Detached". Attaching and detaching can happen implicitly thanks to internal functionality of Entity Framework or explicitly by calling the methods in your code. You have seen that object which is attached to an ObjectContext has its state and its relationships managed by that context. You also know that an object that is detached has no state. And you have dealt with many objects in the coding samples which were automatically attached to the ObjectContext as the result of executing a query and you even added an object or two using the Add and Attach methods. Now you will look a little more closely at explicitly attaching and detaching objects.

8.6.1.1. ObjectContext.Add Use this to add newly created objects that do not exist in the store. The entity will get an automatically generated temporary key and its EntityState will be set to "Added". Therefore when SaveChanges is called, it will be clear to EF that this entity needs to be inserted into the database.

NOTE

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 237

Return to Table of Contents

Beware Added entities which have are joined to other objects. Object Services will attempt to add the related objects to the database as well. You'll learn more about this and how to deal with this behavior later on.

8.6.1.2. ObjectContext.Attach To attach an object to a context, use the ObjectContext.Attach method. The Attach method requires an object that has an existing EntityKey. An object will have an EntityKey if it has come from the data store or if you explicitly create the key. But these objects which you are attaching are assumed to exist in the data store. When you call SaveChanges, the value of the EntityKey is used to update (or delete) the appropriate row by finding its matching ID (most often a Primary Key) in the appropriate table. VB context.Attach(myObject)

C# context.Attach(myObject);

When you attach an entity using the Attach method, the object's EntityState becomes Unchanged. This means that nothing has happened to the entity since the time it was attached.

What Happens to EntityState When You Attach or Detach Entities? When attaching to a context, a brand new ObjectStateEntry is created, its EntityState is Unchanged and both the OriginalValues and CurrentValues are populated with the single set of property values from the incoming entity. When detaching an object, its ObjectStateEntry is removed from the context. What if you have made changes to an entity then detached it and attached it again? As stated above, the newly attached entity will be Unchanged and all of the changes that you may have made earlier will be lost. This is expected behavior for the Entity Framework, but to many developers who are new to working with Entity Framework, this is surprising behavior. Remember that the object doesn't own its state information; an ObjectContext

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 238

Return to Table of Contents

does. If you have an object that is being tracked and has changes, but then you detach the object, what really happens is that the ObjectStateEntry for that object is removed from the context. All of the state is gone including the original values. Poof! When you Attach to a context, a brand new ObjectStateEntry is created. Whatever the property values are for the incoming object are used to populate the OriginalValues and CurrentValues arrays of the ObjectStateEntry.

8.6.1.3. ObjectContext.AttachTo An object needs an EntityKey in order to be change tracked and to be involved in relationships. If you need to attach an object that does not have an EntityKey, you can use the AttachTo method, which also requires that you indicate which EntitySet the object belongs to. With the name of the EntitySet, the Context can dynamically create an EntityKey for the object. When would an object not have an EntityKey? An EntityKey is generally an indication that the object has come from the data store and has some type of a primary key field. Newly added objects are given temporary EntityKeys. But what if you want to work with an object whose data exists in the data store but you are creating that object on the fly in memory without actually retrieving it first? This object will not have an EntityKey by default and you'll need to create one yourself. You can create an EntityKey object using an EntitySet name, the name of the property that is the identifier and the value of that key. As mentioned earlier, it is possible to have composite keys, so you would construct those by first creating KeyValuePairs and then adding those to the EntityKey.

8.6.1.4. Creating an EntityKey on the fly An example where you may need to create an entity key on the fly is if you are creating a new Customer and need to identify the CustomerType for the customer. Customers can be "Standard", "Silver" or "Gold". There is a CustomerType table in the database and a CustomerType entity in the model. In some scenarios you may not have CustomerType entities already in memory. You won't want to create a new CustomerType because EF will attempt to add the type to the database. But the business rule is that all customers start out as Standard customers and the CustomerTypeID for Standard is 0. This is a great scenario for using an EntityKey which you can then use for setting the CustomerTypeReference of the new Customer. The simplest constructor for an EntityKey takes a qualified EntitySet name (EntityContainer name plus EntitySet name), the name of the property that holds the key and the value. Example 8-10 shows a new EntityKey being created for a CustomerType which is wrapped by the CustomerTypes EntitySet. The new EntityKey is then used for the CustomerTypeReference of a new Customer object.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 239

Return to Table of Contents

Example 8-10. Creating a new EntityKey

VB Dim typeEKey = _ New EntityKey("BAEntities.CustomerTypes", "CustomerTypeID", 1) newcust.CustomerTypeReference.EntityKey = typeEKey

C# var typeEKey = new EntityKey("BAEntities.CustomerTypes", "CustomerTypeID", 1); newcust.CustomerTypeReference.EntityKey = typeEKey;

8.6.2. ObjectContext.ApplyPropertyChanges: A Handy Method for Comparing Objects ApplyPropertyChanges is an extremely useful method of ObjectContext because it so handily solves the problem of using detached objects to perform updates. If you have an object in the context and a copy of that object which is detached, you can update the attached object with properties from the detached. The method needs the name of the EntitySet to find the attached entity in and the object that will be used to update the attached entity. The signature for ApplyPropertyChanges is: VB ApplyPropertyChanges(entitySetName as String, changed as Object)

C# ApplyPropertyChanges(string entitySetName, Object changed)

8.6.2.1. Here's how it works. The context looks at the incoming object. If that object does not have an EntityKey, the context can build one based on the metadata of the Entity Set. For example, the Contacts entitySet is defined to return Contact entities and the property of Contact that is used for the EntityKey is ContactID. That's enough information to construct the EntityKey if necessary. With the EntityKey in hand, the context looks for an attached entity in the Contacts EntitySet with a matching EntityKey. Once that is found, it compares the scalar values of the attached entity to the detached and updates any of the properties in the attached entity with new values from the incoming object. As those changes are made, the

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 240

Return to Table of Contents

ObectStateEntry and EntitState are impacted. When it comes time to SaveChanges, the new values will get sent to the server. ApplyPropertyChanges will only update scalar values. It does not touch navigation properties. You will see in later chapters how ApplyPropertyChanges is used to drill down through a graph and perform updates to attached entities.

8.7. Sending Changes Back to the Database Object Services is not only focused on getting data from the database and managing those objects. It manages the full lifecycle of the objects including persisting changes back to the database.

8.7.1. ObjectContext.SaveChanges You have already seen the ObjectContext.SaveChanges method in action in Chapter 7. When SaveChanges is called, it is not the objects, but the ObjectStateEntries that are used to build the various commands for inserting, updating and deleting data. Any ObjectStateEntries that are not "Unchanged" are inspected to determine what commands should be sent to the data store. For each object that needs to be dealt with a Command Tree (similar to the Command Tree used when querying) is built and makes its way to the store provider for conversion to a store command which is then executed in the database. Each command is executed one at a time.

Can Updates, Inserts, and Deletes Be Handled in Bulk? Unfortunately, bulk processing of commands is not something that Entity Framework Version 1 is able to perform intrinsically, However, Alex James, a Program Manager on the Entity Framework team, has written a series of blog posts about how to pull this off with Entity Framework. See http:// blogs.msdn.com/alexj for more information. SaveChanges only sends the minimal data necessary to the data store for changes. If only one value of an entity has changed, the Primary Key and that new value will be in the command.

NOTE

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 241

Return to Table of Contents

In Chapter 13, you'll learn about Optimistic Concurrency and see when additional values are sent to the database for concurrency checking. For deletes, typically only the Primary Key and any foreign keys that are represented as EntityReferences are used in the delete command. Inserts will include all of the necessary values for creating a row in the database. What happens on the store? To see the full process, following is a code sample that performs various operations on address entities. It edits and an address, deletes another and creates a new one using an EntityKey to identify which contact the address is for, then calls SaveChanges. Example 8-11. Modifying, Deleting, and Inserting Entities

VB Dim addresses = (From a In context.Addresses _ Where a.CountryRegion = "Canada").Take(2).ToList 'modify an existing address addresses(0).Street1 = "5 Mountain Road" 'delete an exiting address context.DeleteObject(addresses(1)) 'create a new address Dim newAddress = address.CreateAddress(Nothing, "Home", Now()) With newAddress .Street1 = "25 Flatiron Blvd" .City = "Vancouver" .StateProvince = "BC" .CountryRegion = "Canada" .PostalCode = "V7L 5X3" .ContactReference.EntityKey = _ New EntityKey("BAEntities.Contacts", "ContactID", 11) End With context.AddToAddresses(newAddress) context.SaveChanges()

C# var addresses = (from a in context.Addresses where a.CountryRegion == "Canada" select a).Take(2).ToList(); //modify an existing address addresses[0].Street1 = "5 Mountain Road"; //delete an exiting address

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 242

Return to Table of Contents

context.DeleteObject(addresses[1]); //create a new address var newAddress = Address.CreateAddress(0, "Home", System.DateTime.Now); newAddress.Street1 = "25 Flatiron Blvd"; newAddress.City = "Vancouver"; newAddress.StateProvince = "BC"; newAddress.CountryRegion = "Canada"; newAddress.PostalCode = "V7L 5X3"; newAddress.ContactReference.EntityKey = new EntityKey("BAEntities.Contacts", "ContactID", 11); context.AddToAddresses(newAddress); context.SaveChanges();

SQL Profiler shows that when SaveChanges is called, one update, one insert and one delete command are executed in SQL Server. Figure 8-12. Three SQL commands are executed in the database as a result of the code in Example 8-11.

The generated TSQL for the update shows that only the minimal info, AddressID and the single property that was modified, were sent to the server. Example 8-12. SQL for the Update exec sp_executesql N'update [dbo].[Address] set [Street1] = @0 where ([addressID] = @1) ',N'@0 nchar(15),@1 int',@0=N'5 Mountain Road',@1=2264

The generated TSQL for the insert in Example 8-13 shows that even properties whose values were left as null, in this case Street2, were sent to the server. By default, an insert returns the new row back to the client app so that any default values that were populated by the database as well as the automatically inserted primary key field get merged back into the object cache. Note the "select" clause in the command. If you have overridden the Insert, Update and Delete functions in the model with your own procedures, then the insert will be defined by your stored procedure, not Entity Framework's default dynamic SQL. Example 8-13. SQL for the Insert exec sp_executesql N'insert [dbo].[Address]([Street1], [Street2], [City], [StateProvince], [CountryRegion], [PostalCode], [AddressType], [ContactID], [ModifiedDate]) values (@0, null, @1, @2, @3, @4, @5, @6, @7) select [addressID] from [dbo].[Address] where @@ROWCOUNT > 0 and [addressID] = scope_identity()',

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 243

Return to Table of Contents

N'@0 nchar(16),@1 nchar(9),@2 nchar(2),@3 nchar(6),@4 nchar(7), @5 nchar(4),@6 int,@7 datetime', @0=N'25 Flatiron Blvd',@1=N'Vancouver',@2=N'BC',@3=N'Canada', @4=N'V7L 5X3',@5=N'Home',@6=11,@7='2008-10-14 18:26:42:227'

Not only does the delete command send the primary key of the row to be deleted, but you may not have expected to also see the Foreign key, ContactID in the SQL. The foreign key showed up because when the ObjectContext deleted the Address it also needed to delete the relationship object between that Address and its ContactReference. Because the generated SQL must be generic enough to accommodate a slew of relationship possibilities in the database, you may find that related keys are included in the generated SQL even if they don't seem necessary. One case where it would be necessary to include multiple keys is a database table that might have a combined key made up of multiple fields. Example 8-14. SQL for a Delete exec sp_executesql N'delete [dbo].[Address] where (([addressID] = @0) and ([ContactID] = @1))', N'@0 int,@1 int',@0=2267,@1=10

8.7.2. SaveChanges Returns an Integer A little known fact about the SaveChanges method is that it returns an integer representing the number of ObjectContext objects that were affected. As you will learn in more detail later in this book, this number includes not only entity objects but relationship objects which are also maintained by the ObjectContext. Therefore if you create a new entity and then add that entity to the EntityCollection of another entity, a relationship object is created to represent the relationship between the two entities. Initially that object has an EntityState of "Added" because it is a new object. If you move a child entity from one parent to the other, the relationship object that represented the first relationship is deleted and a new one is created to reflect the new end (the new parent). After the SaveChanges call, all of the changes will be accepted in the ObjectContext and every object's EntityState will become unchanged. So whether that object is an entity or a relationship, it will be counted in the number returned by SaveChanges.

8.7.3. Data Validation with the SavingChanges Event ObjectContext has one public event, SavingChanges. This event occurs when SaveChanges is called and is your only opportunity to validate or impact the entities before the commands are created. The code you insert into SavingChanges will get run before the actual SaveChanges method is performed by the API. Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 244

Return to Table of Contents

In this single location, you can perform validation on all of the entities that are being managed by the ObjectContext. This could definitely be a little daunting as you are more likely used to organizing validation information within individual classes. Unfortunately, with Entity Framework, you'll need to pile it all into one place, or at least make all of the calls to perform validation in this one event.. You'll learn how to implement SavingChanges in the next chapter.

8.7.4. Concurrency Management Data concurrency is the bane of any data access developer trying to answer the question: "What happens if more than one person is editing the same record at the same time?" The more fortunate among us deal with business rules that say "no problem, last one in wins." In this case, concurrency is not a problem. More likely, it's not as simple as that and there is no silver bullet to solve every scenario at once. Be default Entity Framework will take the path of "last one in wins" meaning that the latest update gets applied even if someone else updated the data sin between the time that the user retrieved the data and the saved it. You can customize the behavior using a combination of attributes in the Entity Data Model and methods from Object Services. Chapter 13, Optimistic Concurrency and Exception Handling , will deal with this topic in depth, but here is a short overview of the functionality provided.

8.7.4.1. Optimistic Concurrency Entity Framework uses an Optimistic Concurrency model, which means that it does not lock records in the database, making it possible for others to read and write data in between a user's retrieval and update.

8.7.4.2. ConcurrencyMode In the Entity Data Model, the scalar properties of an entity have an attribute called "ConcurrencyMode". By default this is set to "None". In a typical data application, it is usually particular pieces of data that raise concurrency concerns, rather than an entire row in a table. By setting the Concurrency mode of a particular property to "Fixed", Object Services will use the value of that property to determine if the database row has been changed in a way that you want to be informed about.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 245

Return to Table of Contents

8.7.4.3. OptimisticConcurrencyException When SaveChanges is called, if any of the flagged values have changed in the database an OptimisticConcurrency Exception will be thrown. Chapter 13 will go into great detail about handling these exceptions.

8.7.5. Transaction Support Object Services operations against the data store, such as queries or the SaveChanges method are transactional by default. You can override the default behavior using System.Transaction.TransactionScope, EntityTransaction or one of the other System.Data.Common.DbTransaction classes, such as SqlClient.SqlTransaction. EntityTransaction inherits from DbTransaction as well.

NOTE

Transaction support works only with operations against the store, not operations to objects. By default, the last step of SaveChanges is to accept all changes to the objects. This means that in the ObjectStateEntry, the original values are replaced with the current values and the object's EntityState is set to "Unchanged". This is especially important with respect to values that are generated on the server. This action will use those returned values as well. However when SaveChanges is inside of your own transaction, the changes don't come back from the server until you call dbTransaction.Commit or TransactionScope.Complete. Because of this, you need to set the SaveChanges argument, AcceptChangesDuringSave, to False. Additionally, after the Commit or Complete is called, you will need to manually call ObjectContext.AcceptAllChanges. You'll find more about Transactions in Chapter 14, Making it Real.

8.8. Additional Features 8.8.1. Object Services Supports XML and Binary Serialization Data is serialized in order for it to be transmitted across boundaries and processes, most commonly with remote or message-based services. Entity classes generated from the EDM are extended with the Serializable and DataContractAttribute attributes.

Notice that because you changed the ReadOnly property to True before converting, the EditItemTemplate is a Label, not a TextBox, and won't be editable. The generated Template has syntax that will create a problem. Remove the square brackets around both instances of PrimaryActivity.ActivityName.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 280

Return to Table of Contents

When you run the app you'll see the ActivityName is displayed and not editable when you edit a row. A drop down list is an appropriate way to edit this type of related data.

10.4.1.3. Pick Lists for EntityDataSources To create an available list of Activities for editing Customers, you can use another EntityDataSource control. 1. Add a new EntityDataSource control to the form named ActivityDataSource 2. Configure it to use BAEntities as its ConnectionString and EntityContainer 3. Choose Activities for the EntitySetName Do not check the Enable inserts, updates or deletes checkboxes since this will only be used for selection. There are many properties of the EntityDataSource that are not available in the wizard. You can configure the EntityDataSource using its Properties window or directly editing the markup in Source view. The Activity pick list will be more useful if it's sorted. You can affect this using the OrderBy property of the EntityDataSource. Remember that you will need to use the same Entity SQL syntax that you used with the Query Builder methods. NaN Change the Sort property to it.ActivityName. This task is not specific to the EntityDataSource but one that you would have to do regardless of the data source. The DropDownList can be defined in the UI, but some of the binding needs to be done in the code behind. In the Source, replace the asp:Label inside the EditItemTemplate tags with a DropDownList. The DataSourceID binds it to the new ActivityDataSource and the while the DataTextField and DataValueField define which Activity fields to use for display and value. The SelectedValue property gives you two-way data binding back to the PrimaryActivity.ActivityID property of Customer.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 281

Return to Table of Contents

Now you can edit a customer, select a new Primary Activity then update with ease. You will find that some of the PrimaryActivity selections for customers are null. This will cause a page error to be thrown when you attempt to edit those customers. There's a simple way to avoid the problem. Add the AppendDataBoundItems=True parameter to the drop down list and an asp:ListItem as a child. Select...

10.4.2. What about EntityReferences that are not satisfied by selection lists? Customer has a relationship to Contact, which supplies properties like FirstName and LastName as well as access other data that is related to Contact. The binding does not support this very easily. Rather than selecting from a pick list, it would be more logical to edit FirstName and LastName fields directly in the grid. You can view the related data in the same way you were able to view the ActivityName. Add "Contact" to the Include property, which would now be "PrimaryActivity,Contact" then create a template field bound to Contact.LastName or Contact.FirstName. You can also make this column read-only by using a label in the EditTemplate as you saw with the initial rendering of the ActivityName column. But what about editing? An EntityDataSource will only update the specific entity that it is bound to. If you use Include to bring the additional Contact entity back from the database, it will be ignored during updates. The way to edit the Contact would be to create an EntityDataSource for Contacts and bind it to the Customer. You'll take advantage of another property of EntityDataSource that is not even exposed in the Properties window — the WhereParameters element.

10.4.3. WhereParameters WhereParameters is not the same was the Where clause a query. It's a feature common to ASP.NET DataSource controls that it enables filtering based on values of other controls. Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 282

Return to Table of Contents

This will help solve the problem of editing Customer.Contact entities. You'll create an EntityDataSource for Contacts and filter it based on the ContactID of the currently selected Customer in EntityDataSource1. The WhereParameters gets entered directly in the markup and requires that the EntityDataSource.AutoGenerateWhereClause property be True. This will tell the EntityDataSource to generate the query's Where clause from the WhereParameters. You can change this latter property in the properties window or directly in the markup. 1. Create a new EntityDataSource named ContactDataSource. 2. Change the AutoGenerateWhereClause property to True. 3. Modify the source of the control, adding the WhereParameters, so that the markup now looks as follows.

The WhereParameters is instructing the control to build a WhereParameters that looks for Contacts with ContactID equal to GridView1.SelectedValue. Because the most of the data binding controls return their SelectedValue as a string, the additional DbType attribute ensures that this gets passed in as an Integer. This filter becomes part of the Entity SQL query that is translated and sent to the database each time a new selection is made in the GridView. If you forget to set AutoGenerateWhereClause to True, you will get an exception message that says you can't have WhereParameters when AutoGenerateWhereClause=False.

Because this filter is dependent on the SelectedValue of the GridView, you'll need to enable Selection on the GridView. You can do this in the task window.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 283

Return to Table of Contents

10.4.3.1. A Contact form you can edit Editing the Customers in the grid view and editing a Customer's Contact information will happen as separate actions. This is just the nature of the ASP.NET DataSource controls. In the case of the EntityDataSource this means that it can only create insert, update and delete commands for a single entity, not graphs. Remember that if you don't want to edit, but only view information, you have seen how you can display the contact or other related data directly in the same control as the Customer data. There are two more steps to finish off this part of the example. 1. Open the GridView tasks and Enable Selection if you haven't already done this. 2. Drag a DetailsView onto the form and bind it to the ContactDataSource. Run the form and you can see that as you select different customers, the contact details changes to reflect the contact information of the selected customer. You can edit the contact information if you like. This example has focused on demonstrating how the data binding works between EntityDataSources and data binding controls. You can clean up the grid and details views by formatting the columns but what's more important to keep in mind about this example is that the separation of the customer's information in the GridView and DetailsView is not at all a user-friendly design. As long as Contact and Customer are in two separate entities, you won't be able to edit them as a single unit using the EntityDataSource control. It's still possible to make a logical UI however. The page in Figure 10-8 has reversed the EntityDataSources so that the Customer's WhereParameters defines a dependency on the ContactDataSource. The DetailsView that is bound to the Contacts has paging and is used for navigation. As the user navigates from one contact to another, its Customer data, if any, is displayed in the second DetailsView. Given the particular scenario this makes more sense visually than using a GridView. Figure 10-8. A data driven form that is defined declaratively with EntityDataSource and DetailsView controls not a single line of code.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 284

Return to Table of Contents

NOTE

In the next chapter, you'll learn how to build inheritance into the model and that will make Customer and Contact blend into a single entity. However, modifying your model is not a solution for making it easier for you to build your UI. EntityDataSource is not going to be the solution for every scenario. If you were using a business layer, as you'll learn to do in Chapter 18, you won't be tied down to the rules of the EntityDataSource and you will have more flexibility in building your UI.

10.5. EntityDataSource and Database Hits EntityDataSource is a very convenient control. Because it is completely declarative, you, the programmer make only a small investment in providing data to your website. But you should be aware of what it's doing in the background. The EntityDataSource makes a lot of hits to the database. If you have one EntityDataSource that retrieves Contacts and you edit the contacts in a GridView, here is the rundown on the events that happen using default settings. Page Load A single query is run to retrieve the set of entities required for the control. If it is a grid that uses paging, then the query will retrieve the number of records defined by the page count. If it is a DetailsView or FormView it will retrieve a single entity. If the binding control does any type of paging at all, this includes DetailsView and FormsView, a query is run in advance which gets a count of how many records satisfy the query before the paging records are selected. This means that for most controls, two queries are run every time the page loads User Clicks Edit This causes a page refresh. The initial query (or queries) is run again. If you are binding to another DataSource, for example, the Activity EntityDataSource to populate the drop down list, its query is run as well. The queries are run separately so that will be a number of hits to the database. A query is run against the database to retrieve fresh copy of the entity to be edited.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 285

Return to Table of Contents

User Clicks Cancel This causes the page to refresh again so the initial query (or queries) is run again. User Clicks Update The page is refreshed. An Update command is sent to the database, then the initial query (or queries) is run again. This does not represent every action on the page, but should give you an idea of what's happening on the server side.

10.6. EntityDataSource and Hierarchical Data Many data focused applications are used to present hierarchical data so this next example will focus on Parent/Child/Grandchild data using EntityDataSource controls. This will give you an opportunity to work with EntityCollections. In this example, you will use a variety of methods to populate controls on a web form and take advantage of the EntityDataSource's editing capabilities. This application will let BreakAway employees view Customers and their reservations as well as add payments. You will get a chance to work with a variety of relationships and binding scenarios. And in the course of doing this, you will hit a few speed bumps and learn how to get around them. The form is going to not only use EntityDataSource controls, but you will do some direct data binding to query results as well. The form will have a read-only drop down list of customers to select from. You might consider a few options for populating the drop down list. But what's useful to realize is that the DropDownList will by default use viewstate to retain the values and display text for the items in the list. If you use an EntityDataSource to populate this drop down list, you won't have to worry about that query being called every time the page is refreshed. Figure 10-9. This small web application will let the user interact with hierarchical data.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 286

Return to Table of Contents

10.6.1. Create the Web Application 1. In the same solution that you have been working in, create a new ASP.NET Web Application. As with all of the other apps you have built, copy the connection string from the model project's app.config file into the web.config file and add a reference to the BreakAwayModel project. 2. Build the project so that the EntityDataSource controls will be able to find the Entity Connection string in the web.config file. 3. Drag a DropDownList onto the web form 4. From the list's TaskList, create a new EntityDataSource as you did from the GridView in the previous example. 5. Set the DataSource to BAEntities ConnectionString and EntityContainer. 6. Select the Contacts EntitySet and click Finish.

10.6.2. EntitySQL instead of Query Builder methods The EntityDataSource wizard only allows you select entire entities or properties from those entities. However, for our DropDownList we want to combine the LastName and FirstName properties. It's possible to do this by using your own EntitySQL rather than letting the QueryBuilder methods construct the string based on the various properties of the EntityDataSource. This Entity SQL string will return a ContactID field and a Name field that you can bind to the drop down list. It also returns only those contacts that have a Customer record, therefore you can be sure to only work with Customers as non-Customer contacts do not have reservations, destination or activity preferences and other properties specific to a Customer. SELECT c.contactid, TRIM(c.lastname) + ", " + c.firstname AS Name FROM BAEntities.Contacts AS c WHERE c.Customer IS NOT NULL ORDER BY Name

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 287

Return to Table of Contents

NOTE

Using IS NULL or IS NOT NULL is useful for testing for the existence of an EntityReference. To do this with an EntityCollection, you would use EXISTS or NOT EXISTS with a sub-query into the collection to see if there are any items in the collection. NaN Enter the Entity SQL into the CommandText property of the EntityDataSource EntityDataSource cannot have an EntitySet designated if you want to override the automatically. You selected it in the wizard because the FINISH button is inactive until you select something. NaN Remove Contacts from the EntitySet property

NOTE

If you forget to do this, an exception will be thrown that specifically says you cannot have an EntitySet value if you also have a CommandText value. NaN In the DropDownList's Tasks window, select the Choose Data Source option. NaN Be sure it's data source is pointing to the new EntityDataSource you created. NaN Enter Name for the "data field to display" and contactID for the "data field for the value". Because the properties are coming from the Entity SQL expression, the wizard will not be able to detect the property names and therefore they won't be available in the drop downs. Just type them in directly. NaN Run the app to test out the drop down list.

10.6.3. Viewing the Selected Customer The next step is to create a DetailsView that is dependent on the selection of the DropDownList. A new EntityDataSource will use the WhereParameters to bind to the SelectedValue of the DropDownList. 1. 2. 3. 4.

Drag a DetailsView onto the form. Use its TaskWindow to create a new EntityDataSource control. Set the EntityDataSource's ConnectionString and EntityContainer to BAEntities. Select Contacts as the EntitySet.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 288

Return to Table of Contents

When you complete the EntityDataSource wizard, the DetailsView should automatically populate with the Contact properties. 5. In the Source, add the WhereParameters directly into the markup to bind the new EntityDataSource control to the SelectedValue of the DropDownList. Don't forget to set AutoGenerateWhereClause to True.

Now the DetailsView will update every time an item is selected in the DropDownList. In Figure 10-10 a bit of formatting has been applied, most notably the DataFormatString for the two date fields in the DetailsView was changed to "{0:d}" to affect the default display of the date values. Figure 10-10. The DetailsView will display whichever customer is selected in the DropDownList

So far you haven't done much more than the first example. Now it's time to bring the Customer's Reservation's EntityCollection onto the form.

10.6.3.1. EntityDataSource.Include The Include property maps back to the QueryObject Include method that you have used in previous queries to eager load related data. query= from c in Context.Customers.Include("Reservations") select c The value of the Include requires the same parameter you would use in the Include method. In the properties window, this would not be surrounded by quotes. If you wanted to include the Reservations for the customer, the Include value would be Reservations (with no Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 289

Return to Table of Contents

quotes). If you wanted the Reservations as well as the related Trip data, then the Include path would be Reservations.Trip. This application does in fact need to have the reservation and related trip information for the selected customer. NaN Set the Include value of the Customers EntityDataSource to Reservations.Trip. You won't need to order or filter the EntityDataSource this time because it will be used for the DetailsView and only one customer will be shown at a time.

10.6.3.2. Dynamically or Programmatically Setting the EntityDataSource Control values All of the values that you have set through the wizard or the Properties window are parameters of the control which can also be set directly in markup or programmatically. Here is what the control currently looks like in the Source view of the web page.

You can make changes directly in the markup and even use expressions to populate the values as with any other ASP.NET or HTML control. If you want the option to set any of the parameters at runtime you can set them in the codebehind as well, for example: Customers.Include="Reservations.Trip.Location"

NOTE

This Include path will ensure that the Reservations are eager loaded along with the necessary Trips and Locations so that when you are building your page, you'll have access to the right details about each Reservation. This enables you to change any of the parameters dynamically if you won't know the values until runtime.

10.6.3.3. Filtering the EntityDataSource

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 290

Return to Table of Contents

10.6.3.3.1. The Where property Currently, the Customers EntityDataSource is defined to get all customers. It needs a filter. There are a few ways to filter. Like the OrderBy property, which you used in the Hello World demo above, the Where parameter allows you to insert query logic that will become part of the actual query that the EntityDataSource builds. The value needs to be in the Entity SQL format which you would use with QueryBuilder method parameters. For example, if you wanted to duplicate the query that is called in the form load which filters on only customers who have reservations, you would first need to translate it into a Query Builder method using EntitySQL syntax. Here is that rewritten query without the Select clause which was used to build the anonymous type in the form load. select value c from oftype(BreakAwayEntities.Contacts,BreakAwayModel.Customer) as c where count(select value r.ReservationID from c.Reservations as r)>0

The where clause for this query is "count(select value r.ReservationID from c.Reservations as r)>0" and that is what you would put (again, without the quotes) into the value of the Where property in the EntityDataSource properties window.

10.6.3.3.2. WhereParameters In this application, however, you will not be filtering using the Where property. Instead, you will be taking advantage of a feature common to ASP.NET DataSource controls, the WhereParameters. One of the features of the WhereParameters is that it enables filtering based on values of other controls. This is exactly what is needed here so that the Customers EntityDataSource can be filtered based on the selected value of the DropDownList. The WhereParameters gets entered directly in the markup and requires that the EntityDataSource.AutoGenerateOrderByClause property be True. You can change this latter property in the properties window or directly in the markup. NaN Change the AutoGenerateWhereClause property to True. NaN Modify the source of the control, adding the WhereParameters, so that the markup now looks as follows. Note that the added code is bold.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 291

Return to Table of Contents

NOTE

Visual Studio 2008's Web Designer makes navigating to markup easy. In Design view, select the control whose markup you want to see. Then click Source at the bottom of the Designer window. The source view will be opened up and the markup for the control which you selected in the designer will be automatically selected in the source. The WhereParameters is instructing the control to get build a WhereParameters that looks for Customers with CustomerID equal to DropDownList1.SelectedValue. Because the DropDownList returns its SelectedValue as a string, the additional DbType attribute ensures that this gets passed in as an Integer. This filter becomes part of the Entity SQL query that is translated and becomes the query sent to the database each time a new selection is made in the DropDownList. If you forget to set AutoGenerateWhereClause to True, you will get an exception message that says you can't have WhereParameters when AutoGenerateWhereClause=False.

1. 2. 3. 4. 5.

Bind the DetailsView to the Customers EntityDataSource Select the Details View and click it's SmartTag to open up the DetailsView task. Choose Customers in the Choose Data Source drop down list. Check Enable Editing. Click the Edit Fields so that you can control which fields are displayed and how, much in the same way that that you did with the GridView in the Hello World demo. 6. Set the following fields' Visible property to False: ContactID, AddDate, ModifiedDate and the five navigation fields (Activities.ActivityID, Activities1.ActivityID, CustomerTypes.CustomerTypeID, Locations.LocationID, Locations1.LocationID). 7. Change the ReadOnly property of the InitialDate field to True. 8. Change the DataFormatString of the InitialDate field to {0:d}. This will display the date as a Short Date. Because the Customers EntityDataSource has all of the data logic built into it, there is nothing more that you need to do to the Details view. Each time a new customer is selected in the drop down, the DetailsView will be updated with that Customer's information. The end user will be able to edit and update these customer records as well.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 292

Return to Table of Contents

10.6.3.4. Displaying the Customer's Reservations In this form, the user will not be editing Reservations. Therefore you can take advantage of the Include property of the Contact DataSource and you won't need a separate EntityDataSource for the Reservations. We'll use a ListBox to display the Reservations. 1. Drag a ListBox control onto the form. The model allows for navigation from Contact to Customer to Reservations to Trip and then to Destination. All of these relationships will make it possible to display the detailed reservation information for each contact who is a customer. 2. Add the following to the Include property of the Contact EntityDataSource control. Customer.Reservations.Trip.Destination

At this point, the form should look something like Figure

10.6.3.5. Using Navigation Properties rather than a new EntityDataSource Because the Customers EntityDataSource now uses Include, the all of the entities listed in the Include path will be retrieved from the database when the Contact query is executed. But you still need to push the details into the ListBox and this you'll need to do in code. The EntityDataSource control's Selected event is just the place to do this. The Selected event provides an EntityDataSourceEventArgs object as the parameter, e. This in turn, provides you with a Results property which returns an object, in this case a Contact entity. By casting that result to a Contact type, you can then navigate to the Customer's Reservations and Trip and Destination details.

10.6.3.5.1. Create the EntityDataSource's Selected event. From the events list in the Customers Properties window, double click the Selected event. Because it is possible to select multiple items, the e.Results from the EntityDataSourceSelectedEventArgs contains an IEnumerable of objects. To get the selected Contact, you'll need to cast that collection to the correct entity type using the LINQ Cast method and then extract the first item in the collection. Once that's been done, you can use the TripDetails property you created in the previous chapter to display useful information about the Reservations. If you didn't have that already you would be able to write a LINQ to Objects query against the Reservations and shape the data as you want to display it in the ListBox. Add the following code to the Selected event method.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 293

Return to Table of Contents

VB Private Sub ContactDataSource_Selected _ (ByVal sender As Object, ByVal e As _ System.Web.UI.WebControls.EntityDataSourceSelectedEventArgs)_ Handles ContactDataSource.Selected Dim contact = e.Results.Cast(Of BAGA.Contact)() Dim res = contact.First.Customer.Reservations If res.Count > 0 Then With ListBox1 .DataSource = res.ToList() .DataTextField = "tripdetails" .DataValueField = "ReservationID" .DataBind() .SelectedIndex=0 End With Else ListBox1.Items.Clear() End If End Sub C# protected void ContactDataSource_Selected (object sender, EntityDataSourceSelectedEventArgs e) { var contact = e.Results.Cast(); var res=contact.First().Customer.Reservations; if (res.Count > 0) { ListBox1.DataSource = res.ToList(); ListBox1.DataTextField = "tripdetails"; ListBox1.DataValueField = "ReservationID"; ListBox1.DataBind(); ListBox1.SelectedIndex=0 } }

NOTE

In order for this code to execute, you'll need a reference to System.Data.Entity. This is required because you are working with EntityCollection in a way that is not already supported by the namespace used by EntityDataSource.

10.6.3.5.2. Responding to a Reservation Selection When a customer is selected and their reservations are displayed, the next step is to select a Reservation and view the Payments for that Reservation. This will be achieved by combining a ListView with another EntityDataSource. You'll be entering new payments and therefore, you'll need an EntityDataSource to perform those inserts. We're using the ListView in this example because unlike the GridView, the ListView control easily allows inserting. The new EntityDataSource will use WhereParameters to create a dependency on the selected Reservation from the ListBox. 1. Set Enable AutoPostBack on the ListBox that displays Reservations. This will force the page to respond to a user selecting an item in the ListBox. Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

2. 3. 4. 5. 6.

Page 294

Return to Table of Contents

Add a ListView to the form From the GridView's Tasks, create a new EntityDataSource control. Set the EntityDataSource's Connection and EntityContainer to BAEntities. Set its EntitySetName to Payments Check Enable Automatic Inserts

The ListView will look much better if you do some formatting. If you haven't used a ListView before, you might be surprised that most of its formatting is performed in the markup. The ListView creates templates for Select, Insert, Edit, Alternate and Empty Views. As you will only need Select and Insert you can delete the other sections. Additionally, there are many properties that you won't need. Here is the markup for the ListView after it has been trimmed down. Example 10-1. Formatted ListView after deleting much of the default markup


Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 295

Return to Table of Contents

PaymentDate Amount


NOTE

Notice the formatting that's been added to the ReservationDate property. Date and Currency formatting are controlled by culture info settings which can be controlled programmatically or in the web.config file of your application. Look for Globalization topics in the MSDN documentation for more information on this. NaN Click the Payments EntityDataSource which was created by the wizard. NaN Set the AutoGenerateWhereClause clause property to True. NaN Add the following WhereParameters to the Payments EntityDataSource markup in the source of the page.

This parameter tells the data source to use only query for Payments whose Reservations.ReservationID property is equal to SelectedValue of ListBox1. Like the DropDownList, that value will be a string and needs to be converted to an Integer.

NOTE

The DefaultValue is set to 0 because even if there are no reservations at all, the Payments query will be run. Without the default, all of the payments in the database will be returned. The default forces the query to search for payments whose ReservationID=0 which will return no data.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 296

Return to Table of Contents

Check the previous section on the WhereParameters if you need a reminder of exactly where this needs to be placed in the markup of the data source.

10.6.3.5.3. EntityDataSource.Inserting to help with new payments The ListView has built in functionality for inserting items, but there is one thing missing. You will need to manually add the ReservationID. EntityDataSource has a number of events that you can take advantage of. The Inserting event gives you an opportunity to impact the entity that is about to be inserted into the database. Here is where you can add the ReservationID to the new payment before it goes to the database. The EntityDataSourceChangingEventArgs exposed by the Inserting event (as well as many of the control's events) has an Entity property. In the case of the Inserting event, that property refers to the entity that is about to be sent to the database. Example 10-2 shows the Payment.ReservationReference.EntityKey being used to set the ReservationID. This code should be familiar from the Object Service chapter. The ReservationID comes from the selected item in the ListBox. If no item is selected, the method won't attempt to Example 10-2. Defining the Payment's ReservationReference in the Inserting event VB Private Sub PaymentsDataSource_Inserting _ (ByVal sender As Object, _ ByVal e As _ System.Web.UI.WebControls.EntityDataSourceChangingEventArgs) _ Handles PaymentsDataSource.Inserting Dim newPmnt = CType(e.Entity, BAGA.Payment) newPmnt.ReservationReference.EntityKey = _ New EntityKey("BAEntities.Reservations", "ReservationID", _ CInt(ListBox1.SelectedValue)) End Sub C# protected void PaymentsDataSource_Inserting (object sender, EntityDataSourceChangingEventArgs e) { var newPmnt = (BAGA.Payment)e.Entity; newPmnt.ReservationReference.EntityKey = new EntityKey("BAEntities.Reservations", "ReservationID", Convert.ToInt32(ListBox1.SelectedValue)); }

10.6.4. Test out the app Finally it is time to test out your handiwork. Press F5 to run the application which should look something like Figure 10-11. Select various customers and reservations. You can see

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 297

Return to Table of Contents

how the hierarchical data is automatically presented as you change selections. And all with a minimum of code, highlighting the RAD capabilities of Entity Framework. Figure 10-11. Parent, Child and Grandchild hierarchical data being served up by EntityDataSource controls

10.6.4.1. Remember those stored procedures? It's been a while, so you may not remember mapping functions to the Payment entity for Inserts, Updates and Deletes. Every time you create a new payment now, the Insert stored procedure is getting called. If you were to look in SQL Server Profiler, you can see that the Stored Procedure is being called, rather than a command generated by the database provider. exec [dbo].[InsertPayment] @date='2006-02-01 00:00:00:000', @reservationID=90,@amount=250.0000

10.7. Understanding the EntityDataSource control The EntityDataSource is a very rich control, with many events that you can use to have granular control over its behavior as well as how it relates to other Entities in the application.

10.7.1. EntityDataSource and ObjectContext By default, each EntityDataSource on a page creates its own ObjectContext. It also opens up the CSDL schema files so that it comprehends the schema of the model. If you have more than one EntityDataSource that means you will get multiple ObjectContext objects and multiple connections to the database. Every time a page posts back, the Contexts that were created are dropped. When the page is recreated, the EntityDataSource creates a new ObjectContext for itself. Because the Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 298

Return to Table of Contents

previous context is no longer being used, it will eventually be removed from memory by .NET's Garbage Collector. Like any ObjectContext object, these do not hold onto connections to the database once they have executed their command and retrieved the requested data, so this is not something to worry about, yet good to be aware of if you are focused on resource usage.

10.7.1.1. Using your own context You can override the creation of the individual contexts and thereby have more control over the entities. One way to do this is to instantiate your own context in the form. And force the EntityDataSources to use that. The EntityDataSource has a ContextCreating event, which fires just as the DataSource is about to create its own context. The signature of the event has a parameter that passes in the EntityDataSourceEventArgs. VB EntityDataSource.ContextCreating(ByVal sender As Object, _ ByVal e As System.Web.UI.WebControls. _ EntityDataSourceContextCreatingEventArgs) C# EntityDataSource.ContextCreating(object sender, System.Web.UI.WebControls.EntityDataSourceContextCreatingEventArgs e)

The EventArgs has a context property which represents the context for the data source. By setting that context to your own context, your context is now responsible for the DataSource and the entities that it returns. The following code sample assumes that the context, EDS, has been instantiated elsewhere in the form and is declared as a class level variable. VB Private Sub EDS_ContextCreating(ByVal sender As Object, _ ByVal e As System.Web.UI.WebControls.EntityDataSourceContextEventArgs) _ Handles MyEDS.ContextCreating e.Context = myContext End Sub C# protected void EDS_ContextCreating(object sender, System.Web.UI.WebControls.EntityDataSourceContextEventArgs e) { e.Context=myContext; }

Why create your own context A big benefit of creating a single context is to overcome a problem you encountered in the previous examples. When you have multiple EntityDataSource controls with objects that are related to one another, those objects don't ever get connected and you can't build a graph or update a graph. Relationships between entities will not be recognized unless the

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 299

Return to Table of Contents

entities are managed by the same ObjectContext. Otherwise, even if you have Customers and Reservations that do belong to one another, if they are being managed by separate contexts, you will not be able to traverse from Customers to Reservations or from Reservations to Customers. In other words, Customer.Reservations would result in zero reservations and Reservation.Customer would return null or nothing. While there is also some gain in resource usage by sharing a context, that won't necessarily be a big difference. The ability to control which ObjectContext your entities are being managed by, however, is very powerful.

10.7.2. EntityDataSource Context Events There are a number of events related to the context for the EntityDataSource. Each event offers an opportunity to have more control over the default context used by the data source. Here is a look at some of the more interesting details exposed during these events. ContextCreating e.Context provides a hook to the context before it even exists. As you saw above, this is where you can tell the data source to use another context instead of creating its own. Note that there is no Cancel argument in this creating event. There would be not point to cancelling the creation of a context for the data source as it would not function at all. ContextCreated The EventArgs also returns Context so that you have an opportunity to work with it here. ContextDisposing e.Cancel allows you to stop the context from being disposed. You may need to use this if you are managing the context yourself and know that there will be more work for it to do before the page creation is complete. e.Context returns the context.

10.7.3. EntityDataSource and ViewState The EntityDataSource control not only maintains the current values of its data, but by default it also keeps track of the original values as they were retrieved from the data store. This is necessary for performing the updates to any modified data so that the DataSource Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 300

Return to Table of Contents

knows not only exactly which fields were modified, but if any of the properties in the model have been flagged for concurrency checks the original values are critical. The way that the EntityDataSource maintains the state information is by keeping the original and current values in the ViewState of the ASP.NET page. In doing this, the values are retained across postbacks and then available when it is time to perform an Update. You can modify this behavior with two properties of the EntityDataSource, EnableViewState and StoreOriginalValuesinViewState. Both properties are True by default. If you are new to ASP.NET, you can learn more about ViewState in the MSDN Documentation as well as a variety of other resources. As you will see below, even if you choose not to retain the original values in ViewState, you have opportunities to define original values prior to data updates in the EntityDataSource.Updating event.

10.7.4. EntityDataSource Events and Page Events When a page starts up that has an EntityDataSource, here are the EntityDataSource events in the order that they fire and how they relate to some of the key Page events • • • • • • • •

Page Begin Load Entity Data Source Load Page Being PreRender EntityDataSource ContextCreating EntityDataSource.ContextCreated Page End PreRender EDS ContextDisposing Page Unload

There are also a number of other events related to data modification • • • •

Deleting and Deleted Inserting and Inserted Updating and Updated Selecting and Selected

These events are all opportunities to customize the behavior of your control. As an example, in the sample above, you trapped the Inserting event to add an additional value to an entity that is about to be inserted. Additionally, you used the Selected event to determine which entity had been selected and then populate a ListBox with its related data. Each of these events provides relevant information through their EventArgs variable "e". Here are the ones that are of the most interest. Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 301

Return to Table of Contents

Inserting e.Entity returns the Entity that is being Inserted. If you want to work with this entity, you will need to cast it to its proper type as you did in the sample you just built. e.Cancel gives you an opportunity to Cancel the insert. You would do this by setting the value of e.Cancel to True. Inserted This event fires after the item was inserted into the data store. e.Entity returns the Entity that as just inserted. This includes the new EntityKey because the necessary value was returned from the data store. Remember that if you are letting Entity Framework generate the commands it will get the new key by default. If you are using your own Stored Procedure, as we did for the Payments, this value will only be returned if the procedure sends it back and if you have wired it up in the mappings, which you did at the beginning of the chapter. e.Context gives you access to the Context. e.Exception and e.ExceptionHandled give you an opportunity to trap any problems that may have occurred either by constraints in the model or constraints in the database. Updating e.Entity returns the entity in its current state. You will need to cast the NewEntity to the correct entity type in order to interact with it in detail. e.Cancel, e.Exception, and e.ExceptionHandled are available in this event. Updated The EventArgs provides the same properties as with Updating. Selecting e.DataSource provides many of the EntityDataSource properties so that you can affect them at run time if necessary. By changing the properties in the Selecting event, you can redefine the DataSource prior to the retrieval of data from the store. The properties that can be accessed or changed during this event are: CommandParameters, CommandText, OrderBy, OrderByParameters, Where, WhereParameters. Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 302

Return to Table of Contents

e.SelectArguments provides an opportunity to tweak the query with a few more properties that are not part of EntityDataSource: MaximumRows, RetrieveTotalRowCount, SortExpression, StartRowIndex and TotalRowCount. You can cancel this event with e.Cancel if you need. Selected e.Results provides an array of Entities. You worked with this property in the second example. This event also provides access to the Context, any Exceptions that were thrown and SelectArguments. Deleting e.Cancel (as above) Context. Entity and Exceptions are available in this event. Deleted This provides access to the Context, the entity and any exceptions.

10.7.5. EntityDataSource may not always be the answer EntityDataSource is very convenient for building quick web applications against the Entity Data Model. While it's convenient, there is some resource overhead that may not be desired and more complex applications require business layers so defining the data in the UI might not even be an option. The EntityDataSource will keep track of the EntityState for every entity under its watch, even if you have set the Enable Automatic Insert, Update and Delete properties to False.

10.8. Summary In this chapter you built two different types of small web applications using the EntityDataSource which gave you a hands on opportunity to see how Entities and query results can be used in some simple web application scenarios. ASP.NET Applications can get much more complicated than what you have seen here and in a later chapter you will deal with some more real world scenarios that will make more sense after learning some more concepts and internals about the Entity Framework.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 303

Return to Table of Contents

The web application that you will build for BreakAway Geek Adventures will allow employees to perform one of the most important tasks of any company – collecting payments.

Chapter 11. Advanced Entity Data Models So far in this book, you have worked with models that closely match the database. You have made some simple changes to the names of entities and in one case you have gone deeper to leverage inheritance in the model.

Licensed by Dave Olsen

The Entity Data Model has enormous flexibility when it comes to customizing the model beyond something that is a reflection of your database. This highly customizable conceptual layer is one of the most prominent reasons many developers will choose to use Entity Framework. In this chapter you will learn about the many ways that an Entity Data Model can be customized, the advantages of the customizations and when you would want to take advantage of them. While most of the customization happens in the CSDL layer, there are additional mappings and even storage schema modifications that you can use to create a model that truly describes data in a way that fits very well into your vision of how the data should look. There are a number of modeling techniques related to Stored Procedures. Those will be covered in the next chapter, Implementing Stored Procedures: Beyond the Basics.

11.1. Entity Data Model and the EDM Designer While the designer supports the most common types of customizations, there are a number of specialized EDM features that the designer currently does not support. The impact of this differs depending on which unsupported customization you are using. Here are the various ways that non-supported features can affect the use of the designer: Feature does not appear in the designer. Designer goes into "Safe Mode" when you attempt to open the model in the designer. Safe Mode presents a message that indicates the model cannot be opened in the designer and displays a link to open the model up in XML view. • Mapping Designer goes into safe mode, but CSDL designer displays. • An error is thrown when you attempt to open the model in the designer. • •

AwayEntities.Lodgings as lodge WHERE lodge IS NOT OF(BAGA.BreakAwayModel.Resort)

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 304

Return to Table of Contents

NOTE

Note that the fully qualified namespace is necessary in the parameter. This project references the BreakAway Model project and in my solution, I renamed the project's assembly namespace to BAGA rather than using the default BreakAwayModel.

11.2. Inheritance in the EDM The BreakAway business has a number of different types of Contacts. Some of those contacts are Customers and there is a separate table to keep track of the additional information about these types of Contacts – their preferences, notes and when they first became a Customer. Over the last few chapters, when working with Customers, you have had to constantly go back to the Contacts entity to get the Customers names and addresses. In Object Oriented Programming, when one object is a type of another object, we can use inheritance to share properties. The Entity Data Model supports inheritance as well. There are a number of types of inheritance. The inheritance between Contact and Customer is called Table per Type Inheritance. Let's investigate this one first and modify the model to simplify working with Customers.

11.3. Table per Type Inheritance (TPT) Figure 11-1. TPT Inheritance can be mapped when separate tables in the database are used to describe an inheritance hierarchy. In this case the SalesPeople depends on the Contacts table for some of its data – FirstName and LastName.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 305

Return to Table of Contents

Table per Type, or TPT, Inheritance defines an inheritance that is described in the database with separate tables. There is a 1:0..1 relationship (one entity on one side and either zero or one entity on the other side) between Contact and Customer in the database. This means a Contact could have a Customer entity or not. It also means that a Contact cannot have more than one related Customer entity. The Customer table provides additional information about a subset of the contacts.

11.3.1. Mapping TPT Inheritance 1. Delete the association between Contact and Customer that was created by the Wizard. You can do this by selecting the line that represents the association and deleting it. 2. Add an inheritance object between the two with Contact as the Base type and Customer as the Derived type. The designer provides two ways to add inheritance. One is to drag and drop an inheritance object from the ToolBox. The other is from an entities Context menu. Let's use the context menu method. Right click the Contact Entity. Choose Add, then Inheritance from the context menu. In the Add Inheritance window, select Contact as the base entity and Customer as the derived entity as show in Figure 11-2 Customer will inherit properties from Contact.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 306

Return to Table of Contents

Figure 11-2. Creating an Inheritance between Contact and Customer

3. Delete the EntityKey (ContactID) from the Derived type (Customer). Customer will now depend on the Base type for its EntityKey. 4. Open the Mapping Details for Customer. 5. Map the Customer's new ContactID property (which now comes from the Contact entity) to the ContactID column in the Customers table. When the inheritance is set up, the Customer entity will have a glyph at the top that indicates it is inheriting from Contact. There is an inheritance line between the two entities as well with the arrow pointing to the base entity. Figure 11-3. The new inheritance displayed in the model

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 307

Return to Table of Contents

11.3.2. Association Mappings from Customer need to be recreated Because the ContactID was deleted and replaced, a number of the mappings for Associations involving Customer were broken. If you compile the model, you'll find a list of mapping errors. The associations still exist so you'll need to remap the associations. The Customer entity has six associations defined with other entities. This will be a good lesson in mapping associations, because this task is not very intuitive in the designer.

11.3.2.1. CustomerType Select the association between Customer and CustomerType. You'll see that the CustomerTypeID mapping is still in place, but the ContactID mapping to the Customer's table is gone. Select ContactID in the drop down under Column to map from the ContactID property as shown in Figure 11-4. Figure 11-4. Remapping the ContactID in the association between Customer and CustomerType.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 308

Return to Table of Contents

11.3.2.2. Reservation Remap the ContactID property in the association between Customer and Reservation.

11.3.2.3. Recreate the Activity and Destination Associations from Scratch Although you could edit the existing mappings for the associations, you will be better off completely removing and recreating the four associations between Customer, Activity and Destinations. As you delete the associations, the navigation properties will also disappear. Don't worry, they will return as you recreate the associations.

11.3.2.4. Creating the first Activity Association and Mapping There are two associations between Customer and Activity. 1. Create the First Association Drag an Association control from the Toolbox and attach one end to Customer and the other to Activity. 2. Fix the Navigation Property names. In the Activity entity, rename the newly navigation property Customer to PrimaryPrefCustomers. In the Customer entity, rename Activity to PrimaryActivity. 3. Define the multiplicity between the Entities 4. The relationship between Activity and Customer is 0..1:*, meaning that you can have zero or one Activity for a Customer and each Activity could be mapped to many Customers. In the Properties window, edit the Ends of the association so that the Activity End is 0..1 (Zero or One) and the Customer End is * (Many) as shown in Figure 11-5.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 309

Return to Table of Contents

Figure 11-5. Multiplicity for the Association.

5. Create the Mapping Right click the association and select "Table Mapping" to get to the Association Mappings. When creating association mappings, if there is a Many end of the association, choose its table for the "Maps To..." option. In this case, Customer is on the Many end of the relationship, so select Customers for the mapping. ContactID should map automatically. Map ActivityID to the Customers.PrimaryActivity column. Figure 11-6. Association Mapping for PrimaryActivity

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 310

Return to Table of Contents

11.3.2.5. Create the Second mapping between Customer and Activity Add another association between Customer and Activity. Go through the same steps that you did for the first, changing the navigation properties now to SecondaryCustomerPrefs and SecondaryActivity, fix the multiplicity, then map the association to Customers.SecondaryActivity and Customers.ContactID.

11.3.2.6. Destination Mappings Use the same steps that you did for the two Activity associations to remap the associations used for the Customer's Primary and SecondaryDestination properties. The Navigation Properties for the first association will be PrimaryCustomerPrefs and PrimaryDestination. This association will map to the Customers.PrimaryDestination property. The Navigation Properties for the second association will be SecondaryCustomerPrefs and SecondaryDestination. This association will map to the Customers.SecondaryDestination property.

11.3.2.7. The TimeStamp properties Both the Customer and Contact tables have a TimeStamp column which are to be used for Concurrency checking (this will be handled in Chapter 17). However because the Customer is inheriting all of the properties of Contact, the Customer now has two TimeStamp properties. You could change the name of the TimeStamp property in Customer but for this model, just delete the Customer's TimeStamp property. In Chapter 17 you'll learn more about Concurrency with Inherited types.

11.3.3. Customer is now "OfType" Contact The result of the inheritance is that now the Customer object inherits the Contact properties. You no longer need to navigate to Contact to get the Customer's LastName, FirstName or other Contact properties. You can also navigate directly to the Addresses EntityCollection through the Addresses property.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 311

Return to Table of Contents

In the model this means that the Customers EntitySet is now gone. Customer is now served up from the Contacts entity set. When you request Contacts, those Contacts which have a Customer entity will be returned as Customer types. In order to query for Customers specifically, you will need to use the OfType method to specify which type of Contacts you are seeking. VB From c in Contacts.OfType(Of Customer) Select c C# from c in Contacts.OfType select c;

11.3.4. Create a Test Project To test this new entity as well as the various customizations you will be creating in this chapter, create a new Console Application project. 1. Set it up to use the model as you have done with the previous projects. a. Add a reference to System.Data.Entity b. Add a referenced to the model project c. Copy the connection string from the model's config file into the new project's config file.

NOTE

The config file for a console app is not automatically created, so you'll need to use Add New Item to create the app.config file. If the new project is created for the same language as the model project, you could simply copy the entire app.config file from the model project into the new project. 2. Open the project's main code file (Module1.vb or program.cs) 3. Import the model's namespace at the top of the code file VB Imports BAGA.BreakAwayModel C# using BAGA.BreakAwayModel;

11.3.5. Testing out the TPT inheritance Let's see the inheritance in action. 1. Add the following method to the test module. This will query for Contacts who are Customers. Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 312

Return to Table of Contents

VB Private Sub TPTMap() Using context As New BAEntities Dim query = From c In context.Contacts.OfType(Of Customer)() _ Select c Console.WriteLine("Customers: " & query.Count.ToString) 'query all Contacts Console.WriteLine("All Contacts: " & _ context.Contacts.Count.ToString) Dim newCust As New Customer With newCust .FirstName = "Noam" .LastName = "Ben-Ami" End With context.AddToContacts(newCust) context.SaveChanges() End Using End Sub C# private static void TPTMap() { using (BAEntities context = new BAEntities()) { var query = from c in context.Contacts.OfType() select c; Console.WriteLine("Customers: " + query.Count().ToString()); //query all Contacts Console.WriteLine("All Contacts: " + context.Contacts.Count().ToString()); Customer newCust = new Customer(); newCust.FirstName = "Noam"; newCust.LastName = "Ben-Ami"; context.AddToContacts(newCust); context.SaveChanges(); } }

2. Call the TPTMap method from the main method of the module. 3. Set a breakpoint at the line which instantiates newCust. 4. Run the app. When debugging the Customer results, you can see that the Customer has inherited the LastName and FirstName properties of Contact. When debugging the Contact results, you can see that only the Contact properties are there, even for Contacts who are Customers. Finally, looking at the counts displayed in the output, you'll find that the queried Customers is a much smaller number and is in fact, a subset of contacts. Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 313

Return to Table of Contents

11.3.5.1. Saving the new Customer When the Customer is created in memory, added to the context and then saved to the database with context.SaveChanges, Entity Framework constructs commands to first create a new Contact record and then, based on the newly generated ID returned from the database, it creates the Customer record. Here are the two commands executed on the database. The first inserts a contact and does a SELECT to return the new ContactID and TimeStamp. The second inserts a new Customer using the new ContactID, 851. exec sp_executesql N'insert [dbo].[Contact]([FirstName], [LastName], [Title], [AddDate], [ModifiedDate]) values (@0, @1, null, @2, @3) select [ContactID], [TimeStamp] from [dbo].[Contact] where @@ROWCOUNT > 0 and [ContactID] = scope_identity()', N'@0 nchar(4),@1 nchar(7),@2 datetime2(7),@3 datetime2(7)', @0=N'Noam',@1=N'Ben-Ami',@2='2008-10-23 14:07:33.7290000', @3='2008-10-23 14:07:34.6000000' exec sp_executesql N'insert [dbo].[Customers]([ContactID], [CustomerTypeID], [InitialDate], [PrimaryDesintation], [SecondaryDestination], [PrimaryActivity], [SecondaryActivity], [Notes]) values (@0, @1, null, null, null, null, null, null) select [timestamp] from [dbo].[Customers] where @@ROWCOUNT > 0 and [ContactID] = @0', N'@0 int,@1 int',@0=851,@1=1

Notice that the AddDate and ModifiedDate have values in the Contact insert and the Customer insert has a value for CustomerTypeID. These values are coming from the custom SavingChanges event that was build in the last chapter. The new Customer record is seen both as a Contact type and a Customer type. Therefore as SavingChanges tested for the entity type and populated values based on that, the new Customer entity got the required values for Contact and for Customer.

11.3.6. Specifying or Excluding derived types in queries You can explicitly query for different types within an inheritance structure. To specify a derived type with LINQ or Object Services you can append the OfType method to the Entity Set being queried. Context.Contacts.OfType(Of Customer) Context.Contacts.OfType

There are a variety of other ways to do this in LINQ as well. In Visual Basic, you can use the TypeOf operator for type filtering. From c In context.Contacts _ Where TypeOf c Is Customer Select c From c In context.Contacts _ Where Not TypeOf c Is Customer Select c

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 314

Return to Table of Contents

In C# you can do direct type comparison from c in context.Contacts where c is Customer select c; from c in context.Contacts where !(c is Customer) select c;

Entity SQL also has operators for working with types and in fact, it can filter out types in a way that is not possible with LINQ to Entities. The type operators that you will use most commonly in Entity SQL are OFTYPE IS [NOT] OF Here is an example of how the above queries could be rewritten with Entity SQL. Note that you could do this using Query Builder methods as well. To return only Customer types: SELECT VALUE c FROM OFTYPE(BAEntities.Contacts, BAModel.Customer) AS c

To return Contacts which are not Customer types: SELECT VALUE c FROM BAEntities.Contacts AS c where c IS NOT OF(BaModel.Customer)

Therefore you can also use Object Services and EntityClient with Entity SQL to build more complex queries around types. In LINQ, using the OfType method is the safest way to do type filtering. The reason is because the rest of the query will know that you are working with Customer, not Contact, so any filtering or projection you do can be done based on Customer properties. When placing the type filter in the Where clause, the rest of the query is still based on the type being queried, in the above case, Contact. You won't be able to do projection or filtering on Customer properties.

11.3.7. What if the base entity already exists? What if you have a contact that becomes a customer? This is an important business rule for BreakAway Geek Adventures and one that TPT inheritance doesn't readily support. This isn't to say that Entity Framework doesn't support this scenario, but TPT by definition doesn't support it. Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 315

Return to Table of Contents

Let's look at what may seem like logical options using Entity Framework and why they won't work. The counterpoints provide quite a bit of insight into the workings of Object Services. Add a new customer object As you have seen, adding a new customer will cause a new Contact to be created in the database. Therefore you can't just add a new customer for an existing contact. Create a new customer and populate its contactID with the contactID of the contact. If the contact is not in the context, then Entity Framework will still see this as a new customer and try to add the contact to the database. Get the contact into the context and add a new customer with the same ContactID. Both the Contact and Customer are members of the Contacts entity set. You will not be able to add the customer to the context because a member of the Contacts EntitySet with the same EntityKey already exists in the context. Detach the contact from the context. Set Customer.EntityKey=Contact.EntityKey and Customer.ContactID=Contact.ContactID. Detach the context from the context and attach the customer instead, then SaveChanges. You would be getting closer to a solution with this; except that the Customer will be seen as having no changes and therefore nothing will happen when SaveChanges is called. If you do something to make the Customer "modified" then the resulting command to the database will be to Update a non-existing Customer record and that too, would fail. Use Entity SQL's TREAT operator to "upcast" the Contact to a Customer type. Unfortunately this won't work either. Entity Framework cannot cast from one type to another.

NOTE

In addition to OFTYPE and IS [NOT] OF which you saw earlier, the TREAT operator is another operator that can be used in Entity SQL queries for type inspection.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 316

Return to Table of Contents

While you may want to continue banging your head against the wall with creative hacks, the reality is that TPT inheritance does not support this scenario and even with all of the other benefits that came along with having Customer inherit from Contact, this is a big problem.

Locked into a corner with TPT Inheritance? Early in the classic Design Patterns book (Gamma, Helm, Johnson and Vlissides aka "The Gang of Four"); there is a discussion of Inheritance vs. Composition with the conclusion that one should "favor composition over inheritance". Composition uses building blocks. This would mean reverting the model so that the FirstName and LastName properties of Contact would be accessed from the Customer type using Customer.Contact.FirstName. Inheritance is definitely more convenient for many reasons, but also has its drawbacks. As you can see with TPT Inheritance, the derived type is completely bound to the base type and there is no way to separate the two. You saw this once before in Chapter 8 when considering how to delete a customer record from the database without deleting its related Contact record. And it's something that you should consider prior to designing your Entity Data Model. TPT may be perfect for your business model; it may create some rare annoyances; or it may just not be the right way to go. These are decisions you'll need to make. Given the existing model, the best way to create a Customer for an existing contact would be to use a stored procedure. This would not be a stored procedure that is wired up to the Customer entity through the mappings, but a separate one that can be called explicitly from code. This will allow you to have your cake (the convenience of the derived type) and eat it too (perform functions which TPT Inheritance does not support). Stored Procedures will be discussed later in this chapter and at that time you'll see how to leverage the EDMs flexibility to solve this problem.

11.3.8. TPT with Abstract Types In the current inheritance model, the base type, Contact, is a type that gets instantiated for some entities and Customer is instantiated for others IT is possible to have base types that are Abstract, which means that they are there to help define the structure of entities which derive from them, but they will never be instantiated. If you turned Contact into an Abstract type, however, there will be a few hundred Contacts (those which are not Customers) that will never appear in your application because they won't have an instantiated type to map to. You would have no way of accessing Contacts who are not Customers. Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 317

Return to Table of Contents

To solve this you would need to create derived entities to represent other types of Contacts. What would a derived type just to access the "rest of the" contacts look like? Let's modify the model to see. 1. Open the model in the designer and select the Contact entity. 2. In the Properties window, change the value of the Abstract property to true. You will get a warning saying that existing function mappings will be removed. Since you haven't mapped any stored procedures to the contact entity, this isn't a problem. Click OK 3. Now Contact is an Abstract type. 4. Run the TPTMap method again 5. When the breakpoint is hit, debug the results of the Contact query and you will see that there are only Customers returned. The entire set of data for contacts who are not customers is missing. Create the new derived type: 1. In the EDM Designer, create a new entity and name it NonCustomer. 2. Select Contact from the Base Type drop down list. The other fields in the Add Entity window will become disabled since they don't pertain to a derived type. 3. Click OK. That's it. Because there are no additional fields in this new entity, there's no need to do any mapping. If you were to look in the EDMX, the only instance of "NonCustomer" you will find in the XML (other than the designer information) is this element in the CSDL.

NOTE

If there were fields in the Contact entity that were relevant to a non-customer but not relevant to a customer, you could move them over to the new entity. That scenario would require additional mapping. But in this case, everything you need for NonCustomer is already provided by the Contact abstract type. NaN Rerun the application and again, check out the Contact query results in the debugger when you hit the breakpoint. All of the additional contacts are back as NonCustomers.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 318

Return to Table of Contents

Remember that because you queried for just the Customers first and then all Contacts, the Customers that were pulled into the cache on the first query will be up front. As you can see in Figure 11-7, when looking at the results in debug, you'll need to scroll down past the Customer entities before you see the NonCustomer entities. With the NonCustomer entity in the model, the model will present an error in the Error List that says "Entity type 'NonCustomer' is not mapped." This is an erroneous message due to a bug in the validators. You can ignore it and it will not impact your ability to compile or run the application.

Figure 11-7. When querying the abstract type, Contact, all of the derived types are included in the result.

11.3.9. Other types of Inheritance Additional types of Inheritance supported by the Entity Data Model are covered later in this chapter.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 319

Return to Table of Contents

11.4. Entity Splitting Figure 11-8. Entity Splitting allows a single entity to be made up of data from two or more database tables.

Entity Splitting allows you to map a single entity to more than one table. This scenario can be used when tables share a common key, for example if a contact's personal information is stored in a separate table than their business information. It can only be used when there is a 1:1 relationship between the tables. There is an entity in the model that we have so far ignored — ContactPersonalInfo, which has a ContactID property. The purpose of this table is to provide additional information about Customers that might be useful for BreakAway employees to be aware of when these customers participate in trips. Figure 11-9. The ContactPersonalInfo entity

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 320

Return to Table of Contents

One way that you could link this new entity to Customer would be to create a one to one association between Customers and ContactPersonalInfo using the ContactID. That would make Customer a Navigation property of ContactPersonalInfo and ContactPersonalInfo would be a navigation property of Customer. This wouldn't be very convenient because you would always have to traverse the navigation to get to the properties – for example, Customer.ContactPersonalInfo.BirthDate. Wouldn't it be nice to just call Customer.BirthDate? Entity Splitting can solve this problem very easily, by mapping both the Customer table and the ContactPersonalInfo table to the Customer entity.

11.4.1. Merging Multiple Entities into One Thanks to the Copy & Paste functionality of the designer, you can easily copy the ContactPersonalInfo properties into the Customer entity. Once you have done that, all that's left is to map the Customer entity's new properties back to the appropriate table. 1. Copy and Paste all but the ContactID properties from ContactPersonalInfo into the Customer entity. 2. Delete the ContactPersonalInfo entity from the model. 3. Open the Table Mappings for the Customer entity. 4. At the bottom of the property mappings, select Add a Table or View which will cause a drop down arrow to display to the right of the column as you can see in Figure 11-10. Figure 11-10. Click to map an Entity to additional tables.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 321

Return to Table of Contents

5. Click the drop down arrow and choose the ContactPersonalInfo from the list of available tables in the Store schema. All of the column mappings except ContactID should populate automatically. 6. Map the ContactID column to the ContactID property. 7. Save the model.

11.4.2. Test the Entity Splitting Now you can test the revised entity. In the following example, you'll query the new entity, modifying the returned object, create a new entity and then SaveChanges. These actions will allow you to see how an update and an insert involving the multiple tables are handled behind the scenes for you by the Entity Framework. 1. Add the following method to the project's main code file (Module1.vb or Program.cs) VB Private Sub EntitySplit() Using context = New BreakAwayEntities Dim firstCust = (From c In context.Contacts.OfType(Of Customer) _ Select c).FirstOrDefault firstCust.BirthDate = New Date("1981", "1", "24") Dim newcust = Customer.CreateCustomer(0, "Nola", "Claire", Now, Now) With newcust .HeightInches = 68 .WeightPounds = 138 .DietaryRestrictions = "Vegetarian"

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 322

Return to Table of Contents

End With context.AddToContacts(newcust) context.SaveChanges() End Using End Sub C# private static void EntitySplit() { using (var context = new BAEntities()) { //query for a customer and modify a new property var firstCust = ( from c in context.Contacts.OfType() select c).FirstOrDefault(); firstCust.BirthDate = new System.DateTime(1981, 1, 24); //create a new customer var newcust = new Customer(); newcust.FirstName = "Sanjay"; newcust.LastName = "Nagamangalam"; newcust.HeightInches = 72; newcust.WeightPounds = 168; newcust.DietaryRestrictions = "Vegetarian"; context.AddToContacts(newcust); //save modified customer and new customer to db context.SaveChanges(); } }

2. Add code to call EntitySplit in the main method. 3. Set a breakpoint at the line that instantiates the newcust variable. 4. Run the project When the process stops at the breakpoint, debug the firstCust variable and you can see in the watch window that the new properties of Customer are populated. Figure 11-11. At the breakpoint in the test code, inspect the queried Customer in one of the watch windows.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 323

Return to Table of Contents

A quick check in SQL Profiler shows that when querying for the first customer, an inner join was used to include the values from the ContactPersonalInfo table. The SQL Profiler screenshot in Figure 11-12 This screenshot from SQL Profiler shows the commands executed when editing a Customer and when adding a new customer. The first two commands update the ModifiedDate field in Contact and the BirthDate field in ContactPersonalInfo for the first Customer that was queried and edited. The newly added Customer results first in a Contact being created, then a ContatPersonalInfo record and finally a new row in the Customers table. Figure 11-12. This screenshot from SQL Profiler shows the commands executed when editing a Customer and when adding a new customer..

The first insert is because of the inheritance that you created between Customer and Contact, but the insertion to the ContactPersonalInfo table is thanks to the Entity Splitting that you just defined in the model. Entity Framework is able to work out this customization Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 324

Return to Table of Contents

in the model and translate it into the correct commands in the database without the developer having to worry about the fact that there are a number of tables involved in the query or the modification operations.

11.5. Conditional Mapping Figure 11-13. Conditional Mapping creates a permanent filter on an Entity.

The next area of customization to cover is Conditional Mapping. Conditional Mapping can be used directly when mapping an Entity to the data store or in inheritance scenarios. Here you will look at the first scenario and the second will be covered a little further on. Conditional Mapping places a permanent filter on an entity by defining that an entity will be mapped to data in the database only under certain conditions. Therefore if you have a scenario where you will need to filter data 100% of the time on a particular value, rather than having to add this filter to every single query, you can define it as part of the mapping. As an example, imagine that BreakAway Geek Adventures decided that from now on, they would only provide water related activities. However, they do not want to delete historical data from the database, they could use conditional mapping to ensure that any time Activities were requested it would only be water related activities. Another example would be if rather than filtering by activity type, a Boolean field named "Discontinued" could be introduced into the Activities table in the database. Then in the conditional mapping, you could create a filter that only allows Activities to be returned from the database when Discontinued=0 or False It is possible to use Conditional Mapping in the following ways: [value] Is Null

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 325

Return to Table of Contents

[value] Is Not Null [integer value] e.g. 1 [string value] e.g. Water The designer supports Conditional Mapping, though in the designer, you do not use the quotations around the integer of the string. In the XML, those values will be surrounded by quotations. There is a Category property in the Activity entity which is a string. The following walkthrough will try out the first scenario - which is work solely with Activities whose Category is "Water".

11.5.1. Create a conditional Mapping for the Activity Entity Whatever property you will be using for a conditional mapping must be removed from the entity's scalar properties. See the sidebar for a little more information about this.

Single mappings only, please A field in a table can only be mapped once. Therefore you can have either a mapping to a property or a conditional mapping, but not both. The model validation will be happy to let you know if you have broken this rule. 1. 2. 3. 4. 5.

Select the Activity entity. Delete the Category property from the entity. Open up its Entity Mapping window. Click , then click the drop down arrow that appears. Select Category from the drop down list as shown in Figure 11-14. Figure 11-14. Adding a Conditional Mapping

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 326

Return to Table of Contents

6. In this mapping, you will use the default operator (=) for the value comparison. 7. Under Value/Property, type Water. Figure 11-15 shows what the settings should look like when you are finished. Figure 11-15. Add a conditional mapping to the Activity entry indicating that only rows whose Category value is equal to Water should be returned when querying against this entity.

11.5.1.1. Check out the Is Null/Not Null conditions If you wanted the condition to test for null values, the Operator can be changed by using the drop down and selecting Is. When the Operator is set to Is, the Value/Property becomes a drop down with the options Null and Not Null as shown in Figure 11-16. Figure 11-16. By changing the condition operator to "Is", the value column becomes a drop down list with the options Not Null and Null.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 327

Return to Table of Contents

11.5.2. Test the Conditional Mapping You'll see with this next bit of code that the condition not only filters data coming from the database, but impacts data going into the database as well. 1. Add the following method to the test module. VB Private Using Dim Dim

Sub ConditionalMap() context = New BreakAwayEntities query = From a In context.Activities Select a activities = query.ToList

Dim newAct = New Activity With newAct .ActivityName = "WindSurfing" End With context.AddToActivities(newAct) context.SaveChanges() End Using End Sub C# private static void ConditionalMap() { using (var context = new BAEntities()) { var query = from a in context.Activities select a; var activities = query.ToList(); var newAct = new Activity(); newAct.ActivityName = "WindSurfing"; context.AddToActivities(newAct); context.SaveChanges(); } }

2. Call the ConditionalMap method from the main method of the module. 3. Comment out the call to the EntitySplit method. Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Return to Table of Contents

Page 328

4. Set a breakpoint on the code after query.ToList is called. 5. Run the app. When you hit the breakpoint, take a look at the activities variable in the watch window. You will see that only activities in the Water category were retrieved. The insert is even more interesting. Although the only property you set in code was the ActivityName, take a look at the TSQL that was generated and you will see that Water was inserted into the Category field. exec sp_executesql N'insert [dbo].[Activities]([Activity], [imagepath], [Category]) values (@0, null, @1) select [ActivityID] from [dbo].[Activities] where @@ROWCOUNT > 0 and [ActivityID] = scope_identity()', N'@0 nchar(50),@1 nchar(10)',@0=N'WindSurfing ',@1=N'Water

'

The condition was automatically used in the insert. The condition that all Activity entities should have a Category of "Water" also means that any newly created Activity entities will also have a Category of "Water".

11.5.2.1. What about filtering on other types of conditions? What if you wanted to have any activity except Water? Unfortunately it is not possible to map this directly in the model. There is no operator for "not equals" and it is not possible to map a table column more than once. What you see in the designer, equals combined with an integer or string, Is Null and IsNot Null, is the full extent of what the model is capable of. This also means that in conditional mapping, you can't use operators like greater than or less than or filter on other types, such as a date. However, deeper in the model there is still a way to achieve this using a mapping element called QueryView. There is a section further on this chapter that drills into QueryView so that you can see how to have a lot of flexibility in filtering entities. If it's an option, you may need to resort to adding a new column such as "WaterActivity" or "DiscontinuedActivity" into the database table. Then you can easily create a conditional mapping on the Boolean field.

11.5.2.2. Remove the conditional mapping from Activity and recreate the Category property You may not want to have this conditional mapping in place going forward, so feel free to remove it. You'll need to add the Category property back into the Activity Entity and map it to the Category field in the Activities table. 1. Click the When Category mapping in the Mapping Details. 2. Select from the drop down list.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 329

Return to Table of Contents

3. Right click the Activity entity in the designer and choose Add, then Scalar Property from the context menu. 4. Rename the property to Category. 5. Return to the Mapping Details and map the Category field of the Activities table to the Category Property as shown in Figure 11-17. Figure 11-17. If you remove a condition, don't forget to add the field back into the column mappings of your entity, as with the Category field in the Activity entity.

11.6. Table per Hierarchy Inheritance (TPH) Figure 11-18. Table per Hierarchy Inheritance allows you to define a derived type based on data in a single database table.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 330

Return to Table of Contents

Another type of inheritance supported by the EDM is Table per Hierarchy. Table per Hierarchy, or TPH, Inheritance depends on Conditional Mapping. Rather than include only records that match the condition, the condition is used to define records as different types. Figure 11-18 displays a classic TPH inheritance, where an IsSalesPerson Boolean field in the table is used to determine whether a contact row from the database belongs in the Contact entity or the SalesPerson entity. The BreakAway Lodging entity has a Boolean property called Resort. Let's use this property to define Resort as a new type of Lodging.

11.6.1. Create the Resort derived type 1. 2. 3. 4.

Right click the background of the designer. From the context menu, choose Add, then Entity. Change the EntityName to Resort. Select Lodging from the Base type drop down.

NOTE

Notice that the EntitySet automatically becomes Lodgings and is disabled so that you cannot modify it. Since Resort will inherit from Lodging, it will be part of the Lodgings EntitySet. Notice also that the section for Key Property has become disabled. The Lodging entity will still control the Entity Key, even for derived types. Now that you have the new type defined, how will Entity Framework decide which Lodging records go into the Lodging entity and which go into the Resort Entity? The answer is Conditional Mapping.

11.6.1.1. Use Conditional Mapping to filter Lodging records into the Base or Derived type 1. Delete the Resort property from the Lodging entity.

NOTE

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 331

Return to Table of Contents

2. 3. 4. 5.

As you learned when creating the Conditional Mapping above, you can't map a table column more than once. Since you will be using the Resort property for Conditional mapping, it can't be used in the property mapping. Therefore, there is no need for the Resort property. Open the Mapping Details for the Lodging Entity. Click Select Resort from the condition drop down. Change the condition value to 0.

6. 7. 8. 9.

This condition states that records that get filtered into the Lodging entity will be records whose Resort property equals "0" or False. Select the Resort entity. Open its Mapping Details. Map the entity to the Lodging table. Create a Condition for Resort = 1 (or True).

NOTE

The ContactID and LocationID are foreign keys in the Lodging table. They are taken care of by the Navigation Property/Association combinations in the Lodging entity.

11.6.1.2. Move Resort specific properties to the Resort Entity type. 1. The ResortChainOwner and LuxuryResort properties don't make sense in the Lodging entity. They belong in the Resort entity. 2. Cut and paste these two properties from the Lodging entity into the Resort entity. 3. Open the Mapping Details for Resort. 4. Map the ResortChainOwner and LuxuryResort properties to the appropriate columns into the Lodging table. When these steps are complete the Lodging and Resort types should look as they do in Figure 11-19. Figure 11-19. A conditional mapping is used to determine which rows from the Lodging table belong in Lodging or its derived entity, Resort.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 332

Return to Table of Contents

Setting a Default Value on the Table schema There's one problem that you will see if you try to run code against Lodging right now. The LuxuryResort field is a Booleans. In the database, it is non-nullable and has a Default value of 0. The EDM designer for some reason does not bring the Default value over to the SSDL layer of the model. This creates a problem for the Lodging entity. The Lodging entity maps to the Lodging table but does not map the LuxuryResort or ResortChainOwner columns. Only the Resort entity maps those fields. Because Lodging does not map the fields, the model will throw a run time exception telling you that Lodging doesn't know how to deal with LuxuryResort because it is non-nullable and has no default value. Therefore it wants to populate it. But because the field is not mapped, the entity is unable to modify the value. The only way to correct this is to add the DefaultValue attribute manually into the SSDL. Remember that if you run the Update Model from Database tool, this manual modification to the SSDL will be lost and you will need to add it back in manually again.

1. Open the model in the XML Editor. 2. Search for LuxuryResort as a quick way to find the Lodging table. 3. Verify that you are in the SSDL section of the model. You can tell by the property types which will be database types such as int, nchar and bit. 4. Add DefaultValue="false" to the LuxuryResort property.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 333

Return to Table of Contents



11.6.2. Test the Table per Hierarchy Mapping The following method will help you see the effect of the TPH mapping. You can query for all lodgings, including any derived types or for a specific derived type. What's a little trickier is to query for the subset that is not a derived type. The following queries are executed in unique contexts so that entities that are a result of one query do not merge with entities of another query. This way you can more easily see the impact of the various queries. 1. Add the following method to the test module. VB Private Sub TPHMap() Using context = New BreakAwayEntities Dim query = From lodge In context.Lodgings Console.WriteLine("All Lodgings Results: " & query.Count.ToString) End Using Using context = New BreakAwayEntities Dim query = From lodge In context.Lodgings.OfType(Of Lodging)() Console.WriteLine("NonResort Only Results: " & query.Count.ToString) End Using Using context = New BreakAwayEntities Dim query = From lodge In context.Lodgings.OfType(Of Resort)() Console.WriteLine("Resort Only Results: " & query.Count.ToString) End Using End Sub C# private static void TPHMap() { using (var context = new BAEntities()) { var query = from lodge in context.Lodgings select lodge; Console.WriteLine("All Lodgings: " + query.Count().ToString()); } using (var context = new BAEntities()) { var query = from lodge in context.Lodgings.OfType() select lodge; Console.WriteLine("NonResort Results: " + query.Count().ToString()); }

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 334

Return to Table of Contents

using (var context = new BAEntities()) { var query = from lodge in context.Lodgings.OfType() select lodge; Console.WriteLine("Resort Results: " + query.Count().ToString()); } }

2. Call the TPHMap method from the main method of the module. 3. Run the app. When you see the output of the console window, you may be surprised to see that the second query, which you may have expected to return only non-Resort Lodgings, returned all of the Lodgings, regardless of the Resort filter. All Lodgings Results: 101 NonResort Type Only Results: 101 Resort Type Only Results: 10

Why is this? Even though you put a condition on Lodging that states Resort=0 (false), Lodging is a base type. No matter what, Lodging will return itself and all types that derive from it. With a simple query it is not easy to say "give me the base type but none of its derived types." So even though the condition is there, you'll continue to get back all of the Lodgings, even though with Resort=1.

11.6.3. Abstract Entity Type If you want an easy way to retrieve non-Resort Lodgings, you can create a second derived type that inherits from Lodging to retrieve all of the lodging entities that are not Resorts. In this case, the actual Lodging entity would become an Abstract type because it will never be instantiated. The Lodging entity itself cannot be instantiated and will never return Lodging entities. Instead, the Lodgings EntitySet will only return entities that come from its derived types – Resort and non-Resort. Although you performed this task when creating the NonCustomer entity, the following walkthrough will act as a reminder to show how to turn Lodging into an abstract type and then let you see how the abstract and derived types behave in code. 1. In the designer, create another new Entity type, name it NonResort and set its BaseType to Lodging. 2. Open the mapping details for the NonResort Entity. 3. Map the NonResort Entity to the Lodging table. Because there will be no fields specific to this type, you won't need to do any field to property mapping.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 335

Return to Table of Contents

4. Create a Conditional Mapping for the Resort property using the = operator and the value 0 for the comparison. 5. Validate the model using the designer's context menu. You will see two errors about overlapping partitions. This is because the Lodging entity still has the conditional mapping that matches the conditional mapping you just created for NonResort. Because all of the records are now covered by the conditions in NonResort and Resort, you can turn the Lodging entity into an Abstract type and remove the conditional mapping. 6. Open the Mapping Details for Lodging. 7. Delete the Conditional Mapping. Remember that you can do this by selecting from the drop down. 8. In the Properties Window for the Lodging Entity change the value of Abstract to True. You will get a warning that all function mappings will be removed. This refers to Stored Procedures, but there are none for this type and therefore it's not a problem. 9. Rebuild the model project. 10. Open up the code module and modify the second query so that it gets NonResort types. VB From lodge In context.Lodgings.OfType(Of NonResort)() C# from lodge in context.Lodgings.OfType() select lodge

11. Run the application again. This time you can see that the derived NonResort type makes it simpler to get that group as a whole. All Lodgings Results: 101 NonResort Type Only Results: 91 Resort Type Only Results: 10

11.6.4. Which of these mappings is better? What you have just seen is a demonstration of how TPH inheritance works. If your business rules define that you would never want to get the entire set of types (e.g. all of the Lodgings at once), then it makes sense to have the abstract class in the model and use the derived types to interact with the objects. If your business rules define that there are many cases where you will want to work with all Lodgings, regardless of type, then using the base type without defining it as an abstract class may be preferable.

11.7. Complex Types Complex Types are a very convenient way of encapsulating a set of properties. You may want to do this when you have properties that are common between entities (for example

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 336

Return to Table of Contents

different entities that have properties to contain addresses). You may just want to use a Complex Type to create a better structure in your entity. Imagine that in your model you had a contact entity which contained address properties. You may prefer to navigate through the contact with the address fields were tucked inside a complex type. Therefore, rather than having all of this to deal with when programming: Customer FirstName LastName Street City State Zip Phone

you could encapsulate those properties related to the address into a complex type called Address, then insert Address as a property into the Customer type. Customer FirstName LastName Address Phone

Then to get at the Address information, you can drill in further: Customer.Address.City Custoemr.Address.State

What's really nice is that the complex types are still types, so you can instantiate them and use them outside of their parent entity. However, complex types are not EntityObjects, but ComplexObjects. They don't have EntityKeys and are not contained in their own EntitySet, therefore they cannot be queried for directly or persisted into the database.

11.7.1. Complex Types and the EDM Designer Complex types are one of the mapping types that are not supported by the designer, but you can still create them manually. As mentioned at the start of this chapter, "not supported by the designer" can mean different things. In this case, when there is a complex type defined in the model, you will not be able to open the model up in the designer. When you try to open it up in the designer, you will get the designer's "Safe Mode" display that says the designer is unable to display the file but provides a link to open up the model in the XML Editor. This will be highly inconvenient if you are still in the process of designing your model, but otherwise should not be a showstopper if you find that you will get a lot of benefit from using Complex Types.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 337

Return to Table of Contents

11.7.2. Defining a Complex Type You can create the new complex type in the XML Editor by copying the properties from the Entity that originally contains them and pasting them into a element. ComplexType elements are sibling of EntityType elements Because we have a lot more work to do in the designer after this, you'll need to unwind these changes at the end of this walkthrough. You will be guided to comment out XML rather than deleting it while you modify the model. At the end of the walkthrough you will be able to remove the changes and uncomment the original XML.

As an example, you can create an AddressDetail type that encapsulates the specific properties of the Address entity that are the part of the mailing address, leaving the AddressType and Modified date as scalar properties of Address. The new complex type would look like this:

As shown in Figure 11-20, the Complex Type element gets positioned in the CSDL section as a sibling of the EntityTypes. It is not critical where it is placed relative to other entities. Figure 11-20. When adding a ComplexType to the CSDL, its position in the hierarchy is equal to EntityTypes and Associations.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 338

Return to Table of Contents

11.7.3. Replacing properties with a Complex Type In the Address EntityType, you can now replace those properties with a single property to represent the AddressDetails. Note the new Detail property in the Address and entities:

NOTE

Rather than deleting the properties that are being replaced by the Complex Type, comment them out in the XML. That way, you can easily undo these changes and open the model in the designer as you continue to progress through the book.

11.7.4. Mapping entities with Complex Types The required change to the mappings is not as complicated as you might think. You only need to wrap those properties inside a ComplexProperty tag. Note that the name of the ComplexProperty element, Detail, matches the name used for the property in the entities and that the TypeName attribute points directly to the Complex Types.

11.7.9. Windows Forms DataSource works well with ComplexTypes Like the EntityDataSource, Data Sources in Windows Forms let you work with entities and their properties which are Complex Types fairly easily. Figure 11-23 shows an Object Data Source created from the revised Address entity. Figure 11-23. WindowsForms Data Source reads ComplexType properties such as the Detail property of Address.

You can use the complex type in a Windows Forms which is displayed and updated along with the rest of the entity. You can see in this simple form shown in Figure 11-24, that the complex type properties blend in as though they were scalar properties of Address.

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 345

Return to Table of Contents

Figure 11-24. The AddressDetails ComplexType being used with a Data Source in a Windows Form.

The code for this form doesn't make any special accommodation for the Detail property. Public Class Form1 Private _context As BAEntities Private Sub Form1_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load _context = New BAEntities Dim query = From a In _context.Addresses Select a AddressBindingSource.DataSource = query End Sub Private Sub AddressBindingNavigatorSaveItem_Click _ (ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles AddressBindingNavigatorSaveItem.Click _context.SaveChanges() End Sub End Class C# public partial class Form1 : Form { BAEntities _context; public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { _context = new BAEntities(); var query = from a in _context.Addresses select a; addressBindingSource.DataSource = query; } private void addressBindingNavigatorSaveItem_Click

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 346

Return to Table of Contents

(object sender, EventArgs e) { _context.SaveChanges(); } }

11.7.10. Removing the Complex Types from the Model If you have followed along and modified the model, you may want to undo these changes so that you'll be able to open the model while working through more sample code in this book. 1. Comment out or delete the ComplexType definition for AddressDetail. 2. Comment out delete the Detail property in the Address Entity Type. 3. Uncomment the original properties in the Address Entity Type that you commented out when you began these modifications. 4. Comment out or delete the ComplexProperty elements in the EntitySetMapping for Addresses so that the ScalarProperty elements that you enclosed go back to their original positions. You should now be able to open the model up in the Designer again. You may also need to remove or comment out any code that relates to the AddressDetail Complex Type. The compiler will point them out in the Error List window for you.

11.8. QueryView for Read-Only Entities QueryView is an mapping which allows you to override the default mapping for an EntitySet and return read only data. QueryView is something that you need to enter manually in the XML and belongs in the Mapping layer. A QueryView is actually a query that is expressed using EntitySQL syntax. However, rather than creating the EntitySQL expression against the Conceptual layer of the model, the target of the expression is the Store (SSDL) layer. In other words, when you construct the EntitySQL for a QueryView, the query is written against the elements of the SSDL

Entities from QueryViews don't have to be Read-Only While QueryView returns read-only entities, if you want to use QueryView for some of its other benefits, you can force the entity to be updatable. Entities that are mapped with QueryView are still change tracked by the ObjectContext. However, Entity Framework is not able to automatically generate Insert, Update and Delete commands for these entities. Instead, you can always create function

Programming Entity Framework, 1st Edition Programming Entity Framework, 1st Edition By Julia Lerman ISBN: 9780596156244 Prepared for Dave Olsen, Safari ID: [email protected] Publisher: O'Reilly Media, Inc. Print Publication Date: 2009/01/15 User number: 1717051 © 2008 Safari Books Online, LLC. This PDF is made available for personal use only during the relevant subscription term, subject to the Safari Terms of Service. Any other use requires prior written consent from the copyright owner. Unauthorized use, reproduction and/or distribution are strictly prohibited and violate applicable laws. All rights reserved.

Programming Entity Framework, 1st Edition

Page 347

Return to Table of Contents

mappings, as you did for the Payment entity. Then the entity which came from a QueryView will be affected by SaveChanges. In addition to returning read only entities, another benefit of QueryView is that you can overcome the limitations of conditional mapping. As you saw above, Conditional mapping lets you filter using =, Is Null and Is Not Null. Using a QueryView you can filter with a much wider variety of operators including > and =@startdate AND events.startdate) or less than (