4
votes

I'm trying to save a contact in my program which is a simple phone book in C# and I'm using linq & Entity Framework & when I want to add or change any data I get a run time error

Cannot insert explicit value for identity column in table 'Contact' when IDENTITY_INSERT is set to OFF.

Here's my insert (add) code, on the other hand I don't want to add any data in my primary key which is ID and I want to leave it to my SQL Server.

Thank you all for helping me

public void Save()
{
    using (var Contex = new Phone_BookEntities1())
    {
        var p = from c in Contex.Cantacts
                where c.Cantact1 == Name
                select new { c.Cantact1, c.Number };

        if (!p.Any())
        {
            Ref_Cantact = new Cantact();
            Ref_Cantact.Cantact1 = Name;
            Ref_Cantact.Number = Num;
            Contex.Cantacts.Add(Ref_Cantact);
            Contex.SaveChanges();
        }
    }
} 

EDIT

public partial class Cantact 
{ 
    public string Cantact1 { get; set; } 
    public string Number { get; set; } 
    public int ID { get; set; } 
} 
3
How is your entity configured? Have you defined the identity column to be database-generated? - marc_s
stackoverflow.com/users/13302/marc-s i haven't done that,i'm not sure what that is - Mostafa Bouzari
Can you share the code of the Cantact class? - venerik
Are you using EF with a .edmx model, or with a code-first approach? - marc_s
stackoverflow.com/users/502395/venerik public partial class Cantact { public string Cantact1 { get; set; } public string Number { get; set; } public int ID { get; set; } } } - Mostafa Bouzari

3 Answers

0
votes

You may do this;

    public void Save(string Name, string Num)
    {
          using(var context =  new Phone_BookEntities1())
          {
               var existingContacts = Context.Cantacts.Where( c=>c.Cantact1 == Name); //there can be many contacts with the same name. Use FirstOrDefault and also improve the filtering   criteria
               if(existingContacts.Any())
               {
                    foreach(var contact in existingContacts)
                    {   
                         contact.Number = Num;
                    }
               }else
               {    
                      var Ref_Cantact =  new Cantact(){Cantact1 = Name, Number = Num};
                     context.Cantacts.Add(Ref_Cantact);
               }
               Contex.SaveChanges();
         }
    }
0
votes

you can try this: this will wrap all calls in a transaction, therefore setting identity insert on for the insert statement (Created by EF when calling Add+SaveChanges).

if (!p.Any())
            {
                Ref_Cantact = new Cantact();
                Ref_Cantact.Cantact1 = Name;
                Ref_Cantact.Number = Num;
                using(var trans=Contex.Database.BeginTransaction())
                {
                    Contex.Database.ExecuteSqlStatement("SET IDENTITY_INSERT Contact ON;");
                    Contex.Cantacts.Add(Ref_Cantact);
                    Contex.SaveChanges();
                    trans.Commit();
                }
            }

EDIT: Another possibility would be setting AutoIncrement (DatabaseGeneratedOption.Identity) off, using (in your modelbuilder in context class (or whereever)):

modelBuilder.Entity<Cantacts>().Property(x=>x.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
0
votes

I needed to update my .edmx class in my model