Databases Reference
In-Depth Information
}
In this example, a custom validation method called
ValidateOrderStatus
is associated
with the
OrderStatus
property in the metadata class. The validation method first retrieves
the
ObjectStateEntry
instance that contains the Order entity being validated from the
Items
dictionary of the
ValidationContext
object. It then checks the current
State
of the
entity and only performs the validation if the entity is
Modified
. Because the entity state
could also be
Added
,
Deleted
,
Detached
, or
Unchanged
, you only want to check the
OrderStatus property when it is appropriate based on your business rules. You also want to
access the
OriginalValues
property only when the original values are actually available;
the property throws the
InvalidOperationException
when the entity state is
Added
.
Handling DBNull Values
The
OriginalValues
property of the
ObjectStateEntry
class returns an object of
type
DbDataRecord
, which is shared by the Entity Framework with classic ADO.NET.
Unfortunately, this means that the original
null
values are returned as objects of type
DBNull
and the code has to be prepared to handle them accordingly. In particular,
this means that you cannot simply cast the original OrderStatus value to type
Nullable<Byte>
because
DBNull
values cannot be converted to this type and throw an
InvalidCastException
.
One workaround for this problem is to store
OrderStatus
values in variables of type
Object
and to use the static
Object.Equals
method to compare them. Because it takes the object
type into account, you can safely compare values of type
DBNull
and
Nullable<Byte>
for
equality. Here is a new version of the
ValidateOrderStatus
method, which now correctly
handles the scenario where the original value of the
OrderStatus
is
DBNull
:
public static ValidationResult ValidateOrderStatus(
byte? newStatus, ValidationContext context)
{
var stateEntry = (ObjectStateEntry)
context.Items[typeof(ObjectStateEntry)];
if (stateEntry.State == EntityState.Modified)
{
object oldStatus = stateEntry.OriginalValues[“OrderStatus”];
if (object.Equals(oldStatus, (byte)DataModel.OrderStatus.Fulfilled)
&& !object.Equals(newStatus, (byte)DataModel.OrderStatus.Fulfilled))
{
return new ValidationResult(
“Status of fulfilled orders should not be modified”,
new string[] { “OrderStatus” });
}
}
return ValidationResult.Success;
}