This is a standard Cqrs issue. Look up set based validation on Greg youngs site.
Also, why two IDs? It doesn't sound right.
--
Le doute n'est pas une condition agréable, mais la certitude est absurde.
You already have one
On Thu, Dec 1, 2011 at 4:49 AM, Henrik Olsson <u.henri...@live.se> wrote:
> How do I make the key of the aggregate natural with ncqrs?
--
namespace Test.Domain { #region Root and Entity Classes /// <summary> /// JsonObject is required to mitigate the self referencing loop error from Newtonsoft JSON serializer /// Since we are referencing an Entity /// </summary> [JsonObject(IsReference = true)] public class TestAr : AggregateRootMappedWithExpressions, ISnapshotable<TestAr>
{ [NonSerialized] private List<TestEntity> _entities = new List<TestEntity>(); [AggregateRootId] public Guid TestArId { get; set; } public string TestArData { get; set; } public DateTime CreatedonUtc { get; set; } public DateTime ModifiedOnUtc { get; set; } //Entities public List<TestEntity> TestEntities { get { return _entities; } set { _entities = value; } } #region Constructors public TestAr() { IsArCreated(); EventApplied += ArEventApplied; } public TestAr(Guid testarid, string testardata) : this(testarid) { CreateTestAr(testarid, testardata); } private TestAr(Guid testarid) : base(testarid) { TestArId = testarid; EventApplied += ArEventApplied; } #endregion #region Private Methods /// <summary> /// Fired after NCQRS events are applied /// </summary> /// <param name="sender"></param> /// <param name="e"></param> /// <remarks> /// Can be used to fire subsequent commands/events /// Pumped from the <see cref="IEventHandler{TEvent}"/> event queue on the <see cref="IPublishedEvent{TEvent}"/> bus /// </remarks> private static void ArEventApplied(object sender, EventAppliedEventArgs e) { //Display the event Console.WriteLine(e.Event); } /// <summary> /// Validated that the business AR id exists for use /// </summary> private void IsArCreated() { if (EventSourceId.Equals(Guid.Empty)) { throw new CoreException( "The Test AR has not been created and no operations can be executed on it"). GetException<ApplicationException>(); } } #endregion public override void InitializeEventHandlers() { Map<TestArCreated>().ToHandler(OnTestArCreated); Map<TestArChanged>().ToHandler(OnTestArChanged); Map<TestEntityCreated>().ToHandler(OnTestEntityCreated); } #region Snapshot public TestAr CreateSnapshot() { return this; } public void RestoreFromSnapshot(TestAr snapshot) { TestArData = snapshot.TestArData; CreatedonUtc = snapshot.CreatedonUtc; ModifiedOnUtc = snapshot.ModifiedOnUtc; foreach (var entity in snapshot.TestEntities) entity.SetParent(this); TestEntities = snapshot.TestEntities; } #endregion #region CQRS Commands and Events protected void CreateTestAr(Guid testarid, string testardata) { var clock = NcqrsEnvironment.Get<IClock>(); var e = new TestArCreated { TestArData = testardata, CreatedonUtc = clock.UtcNow() }; ApplyEvent(e); } protected void OnTestArCreated(TestArCreated e) { TestArData = e.TestArData; CreatedonUtc = e.CreatedonUtc; } protected void ChangeTestAr(string testardata) { var clock = NcqrsEnvironment.Get<IClock>(); var e = new TestArChanged { TestArData = testardata, ModifiedonUtc = clock.UtcNow() }; ApplyEvent(e); } protected void OnTestArChanged(TestArChanged e) { TestArData = e.TestArData; ModifiedOnUtc = e.ModifiedonUtc; } protected void CreateTestEntity(Guid testentityid, string entitydata) { var clock = NcqrsEnvironment.Get<IClock>(); var e = new TestEntityCreated { TestEntityId = testentityid, EntityData = entitydata, CreatedonUtc = clock.UtcNow() }; ApplyEvent(e); } protected void OnTestEntityCreated(TestEntityCreated e) { var o = new TestEntity(this, e.TestEntityId); TestEntities.Add(o); } protected void ChangeTestEntity(Guid testentityid, string entitydata) { var o = TestEntities.First(x => x.EntityId == testentityid); o.ChangeTestEntity(entitydata); } #endregion } /// <summary> /// Test Entity Class /// </summary> public class TestEntity : EntityMappedByConvention { public string EntityData { get; set; } public DateTime CreatedOnUtc { get; set; } public DateTime ModifiedOnUtc { get; set; } public TestEntity(AggregateRoot parent, Guid entityId) : base(parent, entityId) { } /// <summary> /// Used to establish the event handlers from the parent AR /// when restored from a snapshot /// </summary> /// <param name="parent"></param> public void SetParent(AggregateRoot parent) { ParentAggregateRoot = parent; SetParentHandlers(parent); } public void ChangeTestEntity(string entitydata) { var clock = NcqrsEnvironment.Get<IClock>(); var e = new TestEntityChanged { EntityData = entitydata, ModifiedOnUtc = clock.UtcNow() }; ApplyEvent(e); } protected void OnTestEntityChanged(TestEntityChanged e) { EntityData = e.EntityData; ModifiedOnUtc = e.ModifiedOnUtc; } } #endregion #region Command and Event Classes [MapsToAggregateRootConstructor(typeof (TestAr))] public class CreateTestAr : CommandBase { public Guid TestArId { get; set; } public string TestArData { get; set; } } [Serializable] public class TestArCreated { public string TestArData { get; set; } public DateTime CreatedonUtc { get; set; } } [MapsToAggregateRootMethod(typeof (TestAr), "ChangeTestAr")] public class ChangeTestAr : CommandBase { [AggregateRootId] public Guid TestArId { get; set; } public string TestArData { get; set; } } [Serializable] public class TestArChanged { public string TestArData { get; set; } public DateTime ModifiedonUtc { get; set; } } [MapsToAggregateRootMethod(typeof (TestAr), "CreateTestEntity")] public class CreateTestEntity : CommandBase { [AggregateRootId] public Guid TestArId { get; set; } public Guid TestEntityId { get; set; } public string EntityData { get; set; } } [Serializable] public class TestEntityCreated { public Guid TestEntityId { get; set; } public string EntityData { get; set; } public DateTime CreatedonUtc { get; set; } } [MapsToAggregateRootMethod(typeof (TestAr), "ChangeTestEntity")] public class ChangeTestEntity : CommandBase { [AggregateRootId] public Guid TestArId { get; set; } public Guid TestEntityId { get; set; } public string EntityData { get; set; } } [Serializable] public class TestEntityChanged : EntitySourcedEventBase { public string EntityData { get; set; } public DateTime ModifiedOnUtc { get; set; } } #endregion }