2

I am trying to follow DDD for my current project. My question is specifically regarding POST request that contains values for my domain model. To simplify, let's say following is my domain model:

class Person
{
    public int Id {get, set};
    public string name {get, set};
}

And below is the entity model backing above domain:

class PersonEF
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id {get, set};
    public string name {get, set};
}

Now when I receive a POST request to create a new Person it doesn't contain the Id as it's supposed to be generated by the database. I first map Person to PersonEF using AutoMapper which sets the Id to 0 in PersonEF and hence the INSERT in database fails. So to fix these my options are:

  1. Name Id as something else in Person. If I do this then I would have to write custom mapping just for Id for GET requests.

  2. Make Id nullable (int?) in both Person and PersonEF and this way auto increment will work, but having key as nullable int doesn't sound like a good idea in itself.

So please suggest the best way to do this.

EDIT

My bad. Code was missing context.SaveOrUpdate(). I added that and it's working as expected.

pb02
  • 23
  • 4
  • 1
    Are you sure an auto-incremented ID is the best way to go? If you need some guidelines to decide on an ID design see [this answer of mine](http://stackoverflow.com/a/31675933/219187). I don't know about the specifics of EF, but GUID IDs may be easier to handle. – theDmi Aug 04 '15 at 12:56

1 Answers1

2

It's hard to say for sure, as the code of most importance, that you should have posted, would be that of your controller action where the mapping and saving occurs. However, I can tell you that the 0 is the default value for an int. This is not due to AutoMapper, or mapping in general, per se. The entity, freshly created, without any other interaction, would still have 0 as the id.

As a result, this should not be causing a problem with saving the entity, or else you'd never be able to save any entity that had an int PK. However, depending on what Entity Framework thinks you're trying to do with the entity, it might cause problems. Namely, you need to make sure that Entity Framework is aware that you're wanting to create this entity and not just update it. Usually, that's achieved by simply adding it to the DbSet:

db.PersonEFs.Add(personEF);

Not sure why you would need to go any farther than that, but if that's not working for some reason, you can be a bit more explicit:

db.Entry(personEF).State = EntityState.Added;

However, really, if you need to do that, there's something else going on that you'd just be masking.

Chris Pratt
  • 232,153
  • 36
  • 385
  • 444
  • Thank you for your comment, I cannot post the actual code due to some policies we have here but it's fairly straightforward. I understand that default value is 0 for int. Are you saying that when I have Id set to 0 in personEF and then I call db.PersonEFs.Add(personEF); it should ignore the 0 and actually insert the auto incremented number ? In other simpler projects where I have used entity model as my domain model (hence no mapping anywhere), I would set other attributes but not touch Id and it just works when I call Add method. – pb02 Aug 03 '15 at 21:01
  • Exactly. The int pk property, since it's non-nullable, has to have *some* value, so it's always `0` by default. In the cases where you didn't touch the id property at all, it still was `0`. By virtue of it's state being "Added", EF should ignore that value. Now, it won't actually be something other than zero until after you commit the changes to the database, though, at which point EF will back fill it with what it PK was on insert. – Chris Pratt Aug 04 '15 at 13:48
  • Thank you. I had a stupid mistake in my code. Updated the question with reason. – pb02 Aug 04 '15 at 14:50