skylake
skylake

Reputation: 417

Entity Framework database-first + uniqueidentity result no new guid id

I cannot generate a new guid id for my primary key. Getting same error every time when I try to create an another user as it wont generate a new guid id.

Violation of PRIMARY KEY constraint 'PK_User'. Cannot insert duplicate key in object 'dbo.User'. The duplicate key value is (00000000-0000-0000-0000-000000000000). The statement has been terminated.

Code:

public partial class User
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public System.Guid Id { get; set; }
    public string UserName { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
}

My UserController code

[HttpGet]
public ActionResult Create() {
    return View();
}

[HttpPost]
public ActionResult Create(User user) {
        if (ModelState.IsValid) {
            db.Users.Add(user);
            db.SaveChanges();

            return RedirectToAction("Index");
        }

        return View(user);
}

How do I automatically generate new guids?

Upvotes: 5

Views: 2189

Answers (5)

Huske
Huske

Reputation: 9296

DatabaseGenerated means that it will be generated by the database. Unless you specified default as NEWID() for your column in your table, you will never get a new value. It will always be the value of Guid.Empty. To get your application to work you can do one of the two things. First you can call Guid.NewGuid() directly from your code and pass the value to Entity Framework. In this case there is no point of keeping the [DatabaseGenerated(DatabaseGeneratedOption.Identity)] as part of your Id C# property. The other solution is to alter the column of your table and add default value to be NEWID() in which case you don't have to worry about generating this value yourself and your DatabaseGenerated attribute would make sense.

Upvotes: 1

DevilSuichiro
DevilSuichiro

Reputation: 1059

Your PK is a GUID, I don't know of any DBMS actually implementing some sort of autoincrement for GUID columns, since that wouldn't make much sense.

That's why you'll have wo switch to another column type or drop the autoincrement (DatabaseGeneratedOption.None) and create new Guid's when you need them.

Your code in this form will never work, since EF won't pass it's Id values to the database (because it's database generated), but the database does not know how to create new key values, so it keeps the default Guid.

Upvotes: 1

Tân
Tân

Reputation: 1

Defining a primary key Id with the return type is a string:

public partial class User
{

    [Key]
    public string Id { get; set; }
    ...
}

[HttpPost]
public ActionResult Create(User user) 
{
    if (ModelState.IsValid) 
    {
        user.Id = Guid.NewGuid().ToString(); // handling new id

        // if you want to check duplicate:
        bool exist = db.Users.SingleOrDefault(x => x.Id == user.Id) != null;

        if (exist)
        {
            // code for duplicate key...
        }

        db.Users.Add(user);
        db.SaveChanges();

        return RedirectToAction("Index");

    }
    return View(user);
}

Upvotes: 1

LateshtClick.com
LateshtClick.com

Reputation: 616

you can do in constructor of class like this

public User()
{
  this.Id= Guid.NewGuid();
}

Upvotes: 1

Sparrow
Sparrow

Reputation: 2583

Your c# code is not generating any GUID because you are instructing it to do so. Your model says that the value of Id is generated by database (DatabaseGenerated(DatabaseGeneratedOption.Identity)) The issue is in your table definition in the database. If you are using SQL server, using SQL server management studio, review your table's definition and make sure that ID is actually defined as 'Identity'

Upvotes: 1

Related Questions