Can anybody share an example business rule to ensure unique values? #1795
-
Hi Everyone, My scenario is simple, I have an editable object, and I would like a business rule to ensure a property contains a unique value. Can anybody share an example of how this is done? I've looked at the Sample code and Business Rules Tutorials, but have not seen any examples which matches my scenario. I can see the Project Tracker has CommandBase objects to check for existence (like ResourceExistsCommand), but these are not actually used anywhere in the solution, and is not a business rule. Could a business rule use the CommandBase objects? Thank you. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
When you say "all existing objects" do you mean in memory (like in a collection) or are you referring to a key value in a database? Assuming it is a key value in a database, then yes, a business rule can make use of a command object, and that's a good way to solve the problem. Another is to create a ReadOnlyBase subclass that returns a boolean result (and that's what'd I would probably do). Something like this (untested code): using System;
using System.Threading.Tasks;
using Csla;
using Csla.Rules;
namespace WpfApp1
{
[Serializable]
public class PersonEdit : BusinessBase<PersonEdit>
{
public static readonly PropertyInfo<int> IdProperty = RegisterProperty<int>(nameof(Id));
public int Id
{
get => GetProperty(IdProperty);
set => SetProperty(IdProperty, value);
}
public static readonly PropertyInfo<string> NameProperty = RegisterProperty<string>(nameof(Name));
public string Name
{
get => GetProperty(NameProperty);
set => SetProperty(NameProperty, value);
}
protected override void AddBusinessRules()
{
base.AddBusinessRules();
BusinessRules.AddRule(new PersonExistsRule(IdProperty));
}
[Create]
[RunLocal]
private void Create()
{ }
}
public class PersonExistsRule : BusinessRuleAsync
{
public PersonExistsRule(Csla.Core.IPropertyInfo IdProperty)
: base(IdProperty)
{
InputProperties.Add(IdProperty);
}
protected override async Task ExecuteAsync(IRuleContext context)
{
int id = context.GetInputValue<int>(PrimaryProperty);
var result = await DataPortal.FetchAsync<PersonExists>(id);
if (result.Exists)
context.AddErrorResult($"Item {id} already exists");
}
}
[Serializable]
public class PersonExists : ReadOnlyBase<PersonExists>
{
public static readonly PropertyInfo<bool> ExistsProperty = RegisterProperty<bool>(nameof(Exists));
public bool Exists
{
get => GetProperty(ExistsProperty);
private set => LoadProperty(ExistsProperty, value);
}
[Fetch]
private async Task FetchAsync(int personId, [Inject] IPersonDal dal)
{
Exists = await dal.ExistsAsync(personId);
}
}
} |
Beta Was this translation helpful? Give feedback.
When you say "all existing objects" do you mean in memory (like in a collection) or are you referring to a key value in a database?
Assuming it is a key value in a database, then yes, a business rule can make use of a command object, and that's a good way to solve the problem. Another is to create a ReadOnlyBase subclass that returns a boolean result (and that's what'd I would probably do).
Something like this (untested code):