Below are some additional code examples that demonstrate how
we could use our Northwind model for other common scenarios.
Query Across Relations
The LINQ query below demonstrates retrieve a sequence of
Product objects based on the name of the Category they belong to. Notice below
how we can write LINQ queries that span both the Product and a sub-property of
its associated Category object. The actual filter is all done in the
database engine itself – so only Product objects get returned to the middle
tier (making it efficient):
Use the Find method to retrieve a single Product
In addition to allowing you to write LINQ queries, EF “Code
First” also supports a “Find()” method on DbSet<T> collections that
allows you to write code like below to retrieve a single instance based on its
ID:
Inserting a New Category
The code below demonstrates how to add a new Category to the
Database:
Notice how we create the Category object, assign properties
to it, then add it to the Context’s Categories collection. We then call
SaveChanges() on the context to persist updates to the database.
Inserting a New Category and Product (and associating
them)
The code below demonstrates how to create a new Category and
a new Product, associate the Product so that it belongs to the new Category,
and then save both to the Database:
Notice above how we are able to have the new Product
reference the newly created Category by assigning its “Category” property to
point to the Category instance. We do not need to explicitly set the
CategoryID foreign key property – this will be done automatically for us when
we persist the changes to the database.
EF uses an pattern called “unit of work” – which means that
it can track multiple changes to a context, and then when “SaveChanges()” is
called it can persist all of them together in a single atomic transaction
(which means all the changes succeed or none of them do). This makes it easier
to ensure that your database can’t be left in an inconsistent state – where
some changes are applied and others aren’t.
In the code snippet above both the Category and the Product
will both be persisted, or neither of them will (and an exception will be
raised).
Update a Product and Save it Back
The code below demonstrates how to retrieve and update a
Product, and then save it back to the database. Earlier I demonstrated
how to use the Find() method to retrieve a product based on its
ProductID. Below we are using a LINQ query to retrieve a specific product
based on its ProductName.
We could make any number of changes (to any existing
objects, as well as add new ones). When we call SaveChanges() they will
all be persisted in a single transaction back to the database.
Default Conventions vs. Custom Mapping Rules
When we created the Product and Category classes earlier, we
used the default conventions in EF “Code-First” to map the classes to/from the
database. This avoided the need for us to specify any custom mapping
rules, and kept our code really concise.
There will definitely be times when you don’t like the shape
of the database your are mapping, though, and want to have your model’s object
model be different. Refer back to my Custom Database Schema Mapping blog post for examples of
how to use EF to specify custom mapping rules. These all work equally
well when mapping existing databases.