Databases Reference
In-Depth Information
Product's
UnitsInStock
, it doesn't work because an
Order_Detail
object might not change
when the order is submitted. Instead, it is better to validate all Order_Detail objects in a
particular order at once when the order status changes to Submitted. Not only does this
approach allow you to validate the unchanged
Order_Detail
objects, it is usually more
efficient from the database access standpoint as well. Here is an extract from the
ValidateSubmittedOrder
method in Listing 9.1 that performs this validation:
Product product = this.Order_Details
.Where(item => item.Product.UnitsInStock < item.Quantity)
.Select(item => item.Product).FirstOrDefault();
if (product != null)
yield return new ValidationResult(product.ProductName + “ is out of
stock”);
To check for out-of-stock products in an order, the
ValidateSubmittedOrder
method iter-
ates over all
Order_Detail
objects of the order, comparing their
Quantity
with the
number of
UnitsInStock
of the product. If any order item does not have enough product
units available, a
ValidationResult
is returned to indicate an error.
This code relies on the
lazy loading
, which is enabled by default in the
NorthwindEntities
class, to access
Product
entity objects. As you recall from our previous discussion, lazy
loading makes writing code easier at the cost of performance. Here is how we could
rewrite the Order validation logic to determine if it has any out-of-stock items in a single
database request (remember that
context
is the
ValidationContext
object passed to the
ValidateSubmittedOrder
method as a parameter):
var entities = (NorthwindEntities)context.Items[typeof(ObjectContext)];
string productName = entities.Order_Details
.Where(item => item.OrderID == this.OrderID
&& item.Product.UnitsInStock < item.Quantity)
.Select(item => item.Product.ProductName).FirstOrDefault();
if (productName != null)
yield return new ValidationResult(productName + “ is out of stock”);
Although the new LINQ query looks similar to the previous version, the key difference is
that this new version uses the
Order_Details
property of the
NorthwindEntities
class,
which returns an
IQueryable<Order_Detail>
instead of the
Order_Details
property of the
Order
class, which returns an
IEnumerable<Order_Detail>
. As a result, instead of using
LINQ to Objects and iterating over the lazy-loaded
Order_Detail
collection in memory of
the application, you now use LINQ to Entities to send a single request the database server,
query the Order_Details and Products tables, and return the name of the first out-of-stock
product.
The
ValidateSubmittedOrder
method retrieves an instance of the
NorthwindEntities
object context from the
ValidationContext
object. As discussed in Chapter 8, the
ValidationContext
allows the
UnleashedObjectContext
to pass the
ObjectStateEntry
object
that stores the entity itself to the validation methods. To make the
NorthwindEntities
object
context available as well, the
Validate
method of the
UnleashedObjectContext
class was
further extended as shown in Listing 9.2.