Business Rule for Uniqueness of a column in Validation Rule implementation

Business Rule for Uniqueness of a column in Validation Rule implementation

Old forum URL: forums.lhotka.net/forums/t/3903.aspx


Jitendra posted on Friday, November 16, 2007

Hi,

We need to check uniqueness for a column by check the assigned values into the database. But when we add a custom rule by using ValidationRules.AddRule(UniquePartyNumber, "PartyNumber") It takes the default value of the property not the newly assigned values.

Here is our code look like:

ValidationRules.AddRule(UniquePartyNumber, "PartyNumber");

private bool UniquePartyNumber(object target, RuleArgs args)

{ try

{

Database db = LinnetDatabaseFactory.CreateDatabase();

string sqlSelect;

sqlSelect = "SELECT COUNT(*) AS COUNT FROM PARTY WHERE PARTY_NUMBER = :PartyNumber AND PARTY_ID <> :PartyId";

DbCommand dbCommand = db.GetSqlStringCommand(sqlSelect);

db.AddInParameter(dbCommand, ":PartyNumber", DbType.String, PartyNumber);

db.AddInParameter(dbCommand, ":PartyId", DbType.Int64, PartyId);

using (SafeDataReader sdrReader = new SafeDataReader(db.ExecuteReader(dbCommand)))

{

if (sdrReader.Read()){

long count = sdrReader.GetInt64("COUNT");

if (count > 0){

throw new PartyNumberNotUniqueException();

return false;}

}

else

{

throw new Csla.DataPortalException("Unable to perform unique Party Number check: No data returned.", this);

return false;

}

}

}

catch (Exception ex)

{

log.Error("Unable to perform unique Party Number check.", ex);

throw;

return false;

}

return true;

}

Please let me know how to pass the newly assigned values into this method.

Thanks,

Jitendra

 

JoeFallon1 replied on Friday, November 16, 2007

I see 3 major problems with the code.

1. The problem of how to get the current value.

2. There is no setting for e.Description - instead you are throwing exceptions. Why?

3. You are querying the database directly - this will break if the app is ever set up to use remoting. You need to use a BO to get the answer. Like a command object or other special object.

Here is my central rule for record checking:

'Rule ensuring a value exists in the database.

'Optionally, you can specify to only run the rule on a New BO

Public Function RecordExists(ByVal target As Object, ByVal e As RuleArgs) As Boolean

Dim ruleArg As RecordExistsRuleArgs = DirectCast(e, RecordExistsRuleArgs)

Dim propertyName As String = ruleArg.PropertyName

Dim propertyDescription As String = ruleArg.PropertyDescr

Dim tableName As String = ruleArg.TableName

Dim fieldValue As String = ruleArg.FieldValue

Dim testWhenNew As Boolean = ruleArg.TestWhenNew

Dim value As String = CallByName(target, propertyName, CallType.Get).ToString

Dim bizObject As Csla.Core.BusinessBase = DirectCast(target, Csla.Core.BusinessBase)

If (testWhenNew = True AndAlso bizObject.IsNew) OrElse (testWhenNew = False) Then

If CheckValue.RecordExists(tableName, value, fieldValue) Then   ' <---  this is a command object

Return True

Else

e.Description = GetDescription(target, propertyName, propertyDescription) & " does not exist."

Return False

End If

Else 'testWhenNew = True AndAlso Not bizObject.IsNew

Return True

End If

End Function

===================================================================================

Public Class RecordExistsRuleArgs

Inherits MyRuleArgs

Private mTableName As String

Private mFieldValue As String

Private mTestWhenNew As Boolean

Public ReadOnly Property TableName() As String

Get

Return mTableName

End Get

End Property

Public ReadOnly Property FieldValue() As String

Get

Return mFieldValue

End Get

End Property

Public ReadOnly Property TestWhenNew() As Boolean

Get

Return mTestWhenNew

End Get

End Property

Public Sub New(ByVal propertyName As String, ByVal tableName As String, Optional ByVal fieldValue As String = "", Optional ByVal testWhenNew As Boolean = False, Optional ByVal propertyDescription As String = "")

MyBase.New(propertyName, propertyDescription)

mTableName = tableName

mFieldValue = fieldValue

mTestWhenNew = testWhenNew

End Sub

Public Overrides Function ToString() As String

Return MyBase.ToString & "?tableName=" & mTableName & "&fieldValue=" & mFieldValue & "&testWhenNew=" & mTestWhenNew

End Function

End Class

===================================================================================

 

Copyright (c) Marimer LLC