0

I have a Ticket table and its Receivers which is a collection. Receiver is a value object.

I defined all in EF Core 2.2 and everything is Okay.

When inserting a new ticket, receivers are added to ticket and would be saved.

For updating ticket, as Value Objects are Immutable, should I update the Receiver table or insert new receivers?

I mean this way : Just update Changed properties

    public void AddOrUpdateReceiver(long? ticketId, long? referenceId, int responsibleId, int category, string note)
    {
        var existingReceiver = _receivers.FirstOrDefault(q => q.ResponsibleId == responsibleId);
        if (existingReciever == null)
        {
            var receiver = new Receiver(ticketId, referenceId, responsibleId, category, note);
            _receivers.Add(receiver);
        }
        else
        {
            existingReceiver.SetNote(note);
            existingReceiver.SetReferenceId(category);
            existingReceiver.SetCategory(category);
        }
    }

Or this way : Insert new row with new Id

    public void AddOrUpdateReceiver(long? ticketId, long? referenceId, int responsibleId, int category, string note)
    {
        var existingReceiver = _receivers.FirstOrDefault(q => q.ResponsibleId == responsibleId);
        if (existingReceiver == null)
        {
            var receiver = new Receiver(ticketId, referenceId, responsibleId, category, note);
            _receivers.Add(receiver);
        }
        else
        {
            existingReceiver = new Receiver(ticketId, referenceId, responsibleId, category, note);
        }
    }
unos baghaii
  • 2,539
  • 4
  • 25
  • 42

2 Answers2

0

I think your code should be like this:

        public void AddOrUpdateReciever(long? ticketId, long? referenceId, int responsibleId, int category, string note)
    {
        var existingReciever = _recievers.FirstOrDefault(q => q.ResponsibleId == responsibleId);
        if (existingReciever == null)
        {
            existingReciever = new Reciever(ticketId, referenceId, responsibleId, category, note);
            _recievers.Add(existingReciever);
        }
        existingReciever.SetNote(note);
        existingReciever.SetReferenceId(category);
        existingReciever.SetCategory(category);
    }

You update the Receiver table.

Gaurav
  • 782
  • 5
  • 12
  • No, I ask should I update the receivers or insert new rows and delete the old ones? – unos baghaii Jan 21 '19 at 05:32
  • Updating or deleting records from table may cause issues when multiple users are accessing that so I wouldn't suggest that. Adding records to the table is the best option. – Gaurav Jan 21 '19 at 05:36
  • So what about the old ones that I don't want them now? – unos baghaii Jan 21 '19 at 06:00
  • If you don't want old receivers than you should not maintain a list for receivers, you should create on each request. I am not sure about the business logic and why you are creating the list. – Gaurav Jan 21 '19 at 06:08
  • Why do you need list of receivers, I mean are you using it in any other method than AddOrUpdateReciever? – Gaurav Jan 21 '19 at 06:12
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/187025/discussion-between-unos-baghaii-and-gaurav). – unos baghaii Jan 21 '19 at 06:13
  • @unosbaghaii can you please mark it as answer as it helped you solve the problem. – Gaurav Jan 24 '19 at 03:44
  • unfortunately my problem is not solved. Value objects are Immutable – unos baghaii Jan 24 '19 at 08:13
0

If a Receiver is a Value Object, then should be immutable. For this reason, that class should not have those setter methods that, presumably, will change the object state. Receivers can only be created, either explicitly or by the ORM layer when they are queried from the DB.

Enrico Sanguin
  • 433
  • 3
  • 12
  • yes it is immutable, for creation, I insert the receivers, my problem is when updating. For updating, should I insert new rows? If i should insert new rows, What should I do with the old ones? Delete all receivers of a Ticket and insert new ones? – unos baghaii Jan 21 '19 at 17:01
  • An object is immutable by design, regardless the context it will be used. It cannot be immutable when inserting a Ticket and mutable when updating. In DDD you express a domain with an object model: so, if in your domain make sense to change the Receivers state, then you should use the Entity pattern instead of the Value Object. If, instead, the Receiver is a Value, your model should only permit operations for adding or removing them from the list and not to modify them. – Enrico Sanguin Jan 22 '19 at 08:39
  • Also this could help: https://stackoverflow.com/questions/679005/how-are-value-objects-stored-in-the-database – Enrico Sanguin Jan 22 '19 at 08:45
  • You mean, if modification is needed, we have to use Entities otherwise we can use VO? – unos baghaii Jan 22 '19 at 10:31
  • Yes. From code you provided, it seems that Receiver has a "lifecycle" and can mutate. If this is the desired model behavior (i.e.: reflects the actual domain rules and operations), then it should be an Entity. Please note that my understanding of your Domain, comes only from the code you provided and general meaning of the terms you used. – Enrico Sanguin Jan 22 '19 at 12:00
  • Yes actually I have a Ticket aggregate root . which every ticket can have many receivers. When Updating ticket, receivers can be modified – unos baghaii Jan 22 '19 at 14:13
  • Can you provide any article or documentation to prove that? – unos baghaii Jan 23 '19 at 05:55
  • That comes from the Entity pattern described in the DDD book. You can find a lot of article searching about "Entity in DDD" or Entity vs Value Object in DDD" – Enrico Sanguin Jan 23 '19 at 08:34
  • I also found very effective this short description about Entities from Wikipedia (https://en.wikipedia.org/wiki/Domain-driven_design): "An object that is not defined by its attributes, but rather by a thread of continuity and its identity. Example: Most airlines distinguish each seat uniquely on every flight. Each seat is an entity in this context. However, Southwest Airlines, EasyJet and Ryanair do not distinguish between every seat; all seats are the same. In this context, a seat is actually a value object." – Enrico Sanguin Jan 23 '19 at 08:34
  • The example also shows that choosing from Entity or VO depends on the actual Domain Bounded Context – Enrico Sanguin Jan 23 '19 at 08:37