Databases Reference
In-Depth Information
Implementing complex business rules, such as order fulfillment, in
BeforeSave
methods
(or database triggers for that matter) leads you down the path where you begin thinking
about all possible permutations of property changes and what they might mean. Not only
does it become difficult to analyze rules upfront, it is just as difficult for someone to learn
and maintain the business rules implemented as a mass of
if
statements later on.
Implementing Entity Interaction Rules as Entity Methods
Alternatively, you can implement a complex business rule as a method in one of the
entity classes. For instance, you could implement the order fulfillment rule as the
Fulfill
method of the
Order
entity class shown here:
partial class Order
{
public void Fulfill()
{
this.OrderStatus = (byte)DataModel.OrderStatus.Fulfilled;
this.ShippedDate = DateTime.Now;
foreach (Order_Detail orderItem in this.Order_Details)
orderItem.Product.UnitsInStock -= orderItem.Quantity;
}
}
Similar to the code previously implemented in the
BeforeSave
method, the
Fulfill
method updates the
ShippedDate
property with the current date and time, iterates
through all child
Order_Detail
objects, and subtracts their
Quantity
from the
UnitsInStock
property of their
Products
. However, instead of comparing the
OrderStatus
property with its original value, the
Fulfill
method itself sets it to
Fulfilled
.
Note that just like in the previous example, the
Fulfill
method relies on the lazy loading
of related entity objects provided by the Entity Framework. Although it makes implemen-
tation of entity interaction rules easy, lazy loading might not be efficient because it results
in multiple database calls to retrieve all Order_Detail entities first, followed by their
respective Product entities, retrieved one at a time in the foreach loop.
Lazy loading functionality in Entity Framework was designed for
desktop
applications,
where the initial response that users can see is more important than total duration of the
operation. The
ObjectContext
can also be a long-living object in a desktop application,
automatically caching previously loaded entities in memory and improving performance
of subsequent operations. However, in web applications, where a new
ObjectContext
is
created for each page request and users do not see anything until all data access is
complete and the entire page is generated, lazy loading can significantly affect perfor-
mance for all users of the system. To avoid the performance hit caused by loading the
individual Product entities separately, take advantage of the
Include
method of the
ObjectQuery
class and load all Order_Detail and Product entities with the order in a single
database query.