How to generate and auto increment Id with Entity Framework

asp.net-web-api c# entity-framework json

Question

Revised entire post.

I'm trying to post the following JSON POST request via Fiddler:

{Username:"Bob", FirstName:"Foo", LastName:"Bar", Password:"123", Headline:"Tuna"}

However I'm getting this error:

Message "Cannot insert the value NULL into column 'Id', table 'xxx_f8dc97e46f8b49c2b825439607e89b59.dbo.User'; column does not allow nulls. INSERT fails.\r\nThe statement has been terminated." string

Though if I manually send a random Id along with the request then all is good. Like so:

{Id:"1", Username:"Bob", FirstName:"Foo", LastName:"Bar", Password:"123", Headline:"Tuna"}

Why does Entity Framework not generate and auto increment the Id's? My POCO class is as follows:

public class User
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public string Id { get; set; }
    public string Username { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Password { get; set; }
    public string Headline { get; set; }
    public virtual ICollection<Connection> Connections { get; set; }
    public virtual ICollection<Address> Addresses { get; set; }
    public virtual ICollection<Phonenumber> Phonenumbers { get; set; }
    public virtual ICollection<Email> Emails { get; set; }
    public virtual ICollection<Position> Positions { get; set; }
}

public class Connection
{
    public string ConnectionId { get; set; }
    public int UserId { get; set; }
    public virtual User User { get; set; }
}

public class Phonenumber
{
    public string Id { get; set; }
    public string Number { get; set; }
    public int Cycle { get; set; }
    public int UserId { get; set; }
    public User User { get; set; }
}

Here is the controller method. When in debug mode and I send the request via Fiddler it breaks at db.SaveChanges(); and gives the error seen a bit above.

    // POST api/xxx/create
    [ActionName("create")]
    public HttpResponseMessage PostUser(User user)
    {
        if (ModelState.IsValid)
        {
            db.Users.Add(user);
            db.SaveChanges();

            HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, user);
            response.Headers.Location = new Uri(Url.Link("DefaultApi", new { id = user.Id }));
            return response;
        }
        else
        {
            return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
        }
    }

What's wrong?

Solution

Change string Id to int instead and remove Data annotations. Renamed the Id to UserId, still following convention, and made changes where necessary in other POCO's to match up with the changes.

1
44
4/18/2013 1:52:12 PM

Accepted Answer

This is a guess :)

Is it because the ID is a string? What happens if you change it to int?

I mean:

 public int Id { get; set; }
46
4/18/2013 12:41:48 PM

Popular Answer

You have a bad table design. You can't autoincrement a string, that doesn't make any sense. You have basically two options:

1.) change type of ID to int instead of string
2.) not recommended!!! - handle autoincrement by yourself. You first need to get the latest value from the database, parse it to the integer, increment it and attach it to the entity as a string again. VERY BAD idea

First option requires to change every table that has a reference to this table, BUT it's worth it.



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow