none
DbUpdateConcurrencyException in Entity Framework Database First

    Question

  • Hi there,

    I asked a question about Entity Framework database first on the stackoverflow but no one knows the solution.It's not a big problem, I don't know why this fault is happening.

    http://stackoverflow.com/q/16248202/2100621

    Any help is meritorious my appreciate.

    Thanks in advance,Regards.


    There are only 10 types of people in the world: those who understand binary, and those who don't.

    Saturday, April 27, 2013 10:10 AM

Answers

  • Hello...

    First thing, I don't understand why you are actually calling "SaveChanges()" when you know user has entered incorrect (negative) phone number.

    Anyway, I'm not completely clear with your explanation. I think we are deviating from the actual issue.

    Below are the few points.. how I actually implement it (I will still use your way of "Add New" and "Save").

    I assume you are using MVC web application as UI.

    1. When user clicks on "Add New", I will display a form (Let's call it as Details form) which has controls with no data. I will maintain a Hidden field which holds Person ID (Unique ID).

    2. User fills in data.. Clicks on Save button.

    3. Even the Hidden field will go to server. In this case, it is empty (as Person is not yet added to database.).

    4. I will validate whether user has entered valid data. If not I will restrict here itself. Else, I will simply add it to database.

    using (var db = new MiscDatabaseEntities())
                    {
                        person = new Person()
                                {
                                    Location = "India",
                                    Name = "Kishore",
                                    Phone = 123
                                };
                        db.People.Attach(person);
                        db.Entry(person).State = EntityState.Modified;
                        db.People.Add(person);
                        db.SaveChanges();
                    }
    5. Now, let say you want to update the Person details. You click on the person whom you want to update.

    6. Same Details form will be displayed. In this case, Hidden field will hold Person ID.

    7. Now, you will make all changes in the form. Click on Save button.

    8. Server receives Person ID as well (from hidden field).

    9. Validates the data.

    10. You will get the person object from the database. Update the properties with the data which you received from UI.

    11. SaveChanges().

    Save Method:

    if(PersonID == null)

    {

    //Validate and Add User to database

    db.People.Add(Person);

    db.SaveChanges();

    }

    else

    {

    var prsonInDb = GetUserFromDB(PersonID);

    prsonInDb .Name = "Name received from UI",

    prsonInDb .Phone = "Number received from UI";

    db.SaveChanges();

    }

    Hope you will be clear.

    Thanks,

    Kishore.

    PS: Mark my previous reply as answer if it answers your actual question.


    Happy Coding, Kishore.

    Monday, April 29, 2013 10:10 AM

All replies

  • Hello..

    How did you generate Entity model's from database?

    If you have used Entity model designer, then open ".edmx" file. Check out the "Concurreny Mode" attribute for each property in the Person's entity. You can do this by checking the properties of each property member in Person. It's value should be set to "None".

    Regards,

    Kishore.

    Saturday, April 27, 2013 11:04 AM
  • Thank you KoyaKishore,

    I generate models from database with ADO.NET Entity Model Wizard window, I open edmx file with xml editor there is just one property contains "ConcurrencyMode" and it sets to none.

    I don't want edit all edmx file and all entity property for every table. I think it's not good idea to resolve this problem. Assume that I have 30 entity and each entity has about 10 property, So I must add (30*10) property manually to edmx file? Why?EF comes to make easier coding not for making everyting harder!

    Thanks again.


    There are only 10 types of people in the world: those who understand binary, and those who don't.


    • Edited by DevePlex Saturday, April 27, 2013 11:52 AM
    Saturday, April 27, 2013 11:51 AM
  • Well.! I did not mean that you have to update all the models. I just wanted to cross check if Concurrency Mode is enabled for any property.

    Below are the few points (With respect to your piece of code) on how Entity Framework handles concurrency conflicts.

    When you set dbContext's entity state as Modified, EF assumes that there are few changes done to the entity. So SaveChanges method actually finds the number of rows affected. In your case, you are explicitly saying that your entity is Modified, but no data is actually added/inserted (You haven't called Add method). So EF gets to know that number of rows affected are zero, and throws DbUpdateConcurrency exception.

    You have two options to resolve the issue.

    1. Call Add method after setting Entity state as Modfied.

    using (var db = new MiscDatabaseEntities())
                    {
                        person = new Person()
                                {
                                    Location = "India",
                                    Name = "Kishore",
                                    Phone = 123
                                };
                        db.People.Attach(person);
                        db.Entry(person).State = EntityState.Modified;
                        db.People.Add(person);
                        db.SaveChanges();
                    }


    2. Set Entity state as Added

     using (var db = new MiscDatabaseEntities())
                    {
                        person = new Person()
                                {
                                    Location = "India",
                                    Name = "Kishore",
                                    Phone = 123
                                };
                        db.People.Attach(person);
                        db.Entry(person).State = EntityState.Added;
                        //db.People.Add(person);
                        db.SaveChanges();
                    }

    This is a very high level explanation about Concurrency Conflicts in EF. To get the complete idea on Concurrency conflicts... Do read about OptimisticConcurrency in Entity Framework. You will actually understand why EF is bothered about "Number rows affected" when you read Update scenarios using OptimisticConcurrency.

    Thanks,

    Kishore.

    • Edited by KoyaKishore Sunday, April 28, 2013 4:12 AM
    • Proposed as answer by KoyaKishore Tuesday, April 30, 2013 4:16 PM
    Sunday, April 28, 2013 4:09 AM
  • Thanks KoyaKishore for your answering.

    In your case, you are explicitly saying that your entity is Modified, but no data is actually added/inserted (You haven't called Add method). So EF gets to know that number of rows affected are zero, and throws DbUpdateConcurrency exception.

    I called SaveChange() method for recently added method before it modified. In before scenario when you add a person with incorrect phone number, you first click on the Save button and then you see oh...no you enter a incorrect phone number, So here data is actually added/inserted (I Called Add method first).

    //First of all user click on the "Save" button and it call this method.
    public void AddNew(Models.Person person)
            {
                if (person == null)
                    return;
    
                _context.People.Add(person);
                _context.SaveChanges();
            }


    You have two options to resolve the issue.

    1. Call Add method after setting Entity state as Modfied.

    using (var db = new MiscDatabaseEntities())
                    {
                        person = new Person()
                                {
                                    Location = "India",
                                    Name = "Kishore",
                                    Phone = 123
                                };
                        db.People.Attach(person);
                        db.Entry(person).State = EntityState.Modified;
                        db.People.Add(person);
                        db.SaveChanges();
                    }


    2. Set Entity state as Added

     using (var db = new MiscDatabaseEntities())
                    {
                        person = new Person()
                                {
                                    Location = "India",
                                    Name = "Kishore",
                                    Phone = 123
                                };
                        db.People.Attach(person);
                        db.Entry(person).State = EntityState.Added;
                        //db.People.Add(person);
                        db.SaveChanges();
                    }

    Both options add an entity twice in database, one with incorrect phone number and another with correct phone number!

    PS:

    In my application when a user want to add a new record he must click on the "Add New" button. And then he must click on the "Save" button to save new record to database, it mean if he doesn't click on the "Save" button nothing inserted/added to database.

    If he want modify a record, he changes his data fields and then he click on the "Save" button to make changes to database.

    All modified stuff that their records are added before running current program, modified well, and updated in database successfully but recently new added record in current run does not updated in database and throws DbUpdateConcurrency exception.

    If my "Add" or "Save" UI method is not actually good method in a business application I happy to know what is your idea to handle that "How to user add or modify data on a form". I handle every changes in one "Save" method.

    Thank you.


    There are only 10 types of people in the world: those who understand binary, and those who don't.



    • Edited by DevePlex Monday, April 29, 2013 4:07 AM
    Monday, April 29, 2013 4:01 AM
  • Hello...

    First thing, I don't understand why you are actually calling "SaveChanges()" when you know user has entered incorrect (negative) phone number.

    Anyway, I'm not completely clear with your explanation. I think we are deviating from the actual issue.

    Below are the few points.. how I actually implement it (I will still use your way of "Add New" and "Save").

    I assume you are using MVC web application as UI.

    1. When user clicks on "Add New", I will display a form (Let's call it as Details form) which has controls with no data. I will maintain a Hidden field which holds Person ID (Unique ID).

    2. User fills in data.. Clicks on Save button.

    3. Even the Hidden field will go to server. In this case, it is empty (as Person is not yet added to database.).

    4. I will validate whether user has entered valid data. If not I will restrict here itself. Else, I will simply add it to database.

    using (var db = new MiscDatabaseEntities())
                    {
                        person = new Person()
                                {
                                    Location = "India",
                                    Name = "Kishore",
                                    Phone = 123
                                };
                        db.People.Attach(person);
                        db.Entry(person).State = EntityState.Modified;
                        db.People.Add(person);
                        db.SaveChanges();
                    }
    5. Now, let say you want to update the Person details. You click on the person whom you want to update.

    6. Same Details form will be displayed. In this case, Hidden field will hold Person ID.

    7. Now, you will make all changes in the form. Click on Save button.

    8. Server receives Person ID as well (from hidden field).

    9. Validates the data.

    10. You will get the person object from the database. Update the properties with the data which you received from UI.

    11. SaveChanges().

    Save Method:

    if(PersonID == null)

    {

    //Validate and Add User to database

    db.People.Add(Person);

    db.SaveChanges();

    }

    else

    {

    var prsonInDb = GetUserFromDB(PersonID);

    prsonInDb .Name = "Name received from UI",

    prsonInDb .Phone = "Number received from UI";

    db.SaveChanges();

    }

    Hope you will be clear.

    Thanks,

    Kishore.

    PS: Mark my previous reply as answer if it answers your actual question.


    Happy Coding, Kishore.

    Monday, April 29, 2013 10:10 AM