Is there
any "standard" way to implement the validation rule in which i need to interact with DB?
An option is certainly a command object - what is the sort of validation rule you're looking to implement?
Thank you for answer!
The situation is:
When admin
process request he must view all brokenrule. One of the rule is:
“check is
there any object in DB with the “serial number” from request?”.
I think I follow you.
If it's OK if it's just checked when the admin opens it, you might just return a value from the DB on the fetch request - maybe server request id(s) / names that have the same serial number (but that are different objects than the one you're retrieving). So a collection of ServerRegisterRequestInfo lightweight objects, named as _duplicateSerials). You might just grab a separate result set for the duplicates and pass the data reader along to the collection on the main BO fetch.
If you fetch a collection you can display the ID's to the admin (and perhaps some navigation to the other objects) as well as utilize it in a business rule - is the collection count greater than 0? then the warning rule is broken.
Hope that helps.
So there is a server register request object - I'm not sure if you care about the broken rule (warning) at the time the user is working with it, but let's just assume you do.
I would want this rule to be dependant on the serial number property.
So, you'll create a rule attached to the serial number property - we'll call it "ValidCertificateSerialNumberRequired".
This rule will be triggered whenever the serial number property changes. You should also trigger it in when the user request object is fetched (some people may do a check rules on all properties when fetching an object - if you do, it'd be checked - if you don't, you should do a checkrule on the serial number property - it'll trigger the rule handler).
The code below will obviously need to be debugged/tweaked, I just tried to whip something together...
We'll first create a simple class to serve as a result of the command to give us not only whether the serial number exists under another user request but also the list of user requests where this is the case:
[
Serializable()] public class SerialNumberCheckResult{
private List<int> _userRequestIds = new List<int>(); /// <summary> /// Gets the list of User Request Ids containing this Serial Number (may be empty). /// </summary> public List<int> UserRequestIds{
get { return _userRequestIds; }}
private bool _exists; /// <summary> /// Gets whether the serial number exists in the database under a different User Request /// </summary> public bool Exists{
get { return _exists; }}
internal SerialNumberCheckResult(List<int> userRequestIds, bool exists){
_userRequestIds = userRequestIds;
_exists = exists;
}
}
Then, within your UserRequest class, you'd have this inner private command class:
/// <summary> /// This command is used to determine if a particular serial number exists in the database. /// Also, what User Request IDs have that serial number /// </summary>[
Serializable()] private class SerialNumberExistsCommand : CommandBase{
private int _serialNumberToCheck; private SerialNumberCheckResult _commandResult; public SerialNumberCheckResult CommandResult{
get{
return _commandResult;}
}
public SerialNumberExistsCommand(int serialNumberToCheck){
_serialNumberToCheck = serialNumberToCheck;
}
protected override void DataPortal_Execute()
{
List<int> matchList = new List<int>(); using (SqlConnection cn = new SqlConnection(Database.ActiveDatabase)){
cn.Open();
using (SqlCommand cm = cn.CreateCommand()){
cm.CommandType =
CommandType.StoredProcedure;cm.CommandText =
"getUserRequestsWithSerialNumber"; // Return all User Request Ids with a matchcm.Parameters.AddWithValue(
"@serialNumber", _serialNumberToCheck);System.Data.SqlClient.
SqlDataReader dr = cm.ExecuteReader(); while (dr.Read()){
matchList.Add(dr[
"UserRequestId"]);}
dr.Close();
}
}
_commandResult =
new SerialNumberCheckResult(matchList, matchList.Count > 0);}
}
I'd then have a static method in your User Request class to make this logic reusable
/// <summary> /// Returns whether a specified Query exists in the database using the ID. /// </summary> public static SerialNumberCheckResult SerialNumberExists(int serialNumberToCheck){
SerialNumberExistsCommand existsCommand;existsCommand =
DataPortal.Execute<SerialNumberExistsCommand >(new SerialNumberExistsCommand (serialNumberToCheck)); return existsCommand.CommandResult;}
And last but not least, your rule (by the way, I'd recommend using the strongly typed generic rules, but no biggie):
private static bool ValidCertificateSerialNumberRequired(object target, Csla.Validation.RuleArgs e){
SerialNumberCheckResult existsResult = UserRequest.SerialNumberExists(((UserRequest)target).SerialNumber); if (existsResult.Exists){
e.Description =
"Duplicated Serial Number!"; // Note, you can store the list of user requests conflicting // in a class variable or list them in the error message. // The list of problem children are in existsResult.UserRequestIds return false;}
else{
return true;}
}
Copyright (c) Marimer LLC