0

I use entity framework 2.2.6. I have AddOrUpdate method. When client try to operate(insert or update) on entity I check if entity exist on db by unique values and I set old data id value to new data id value and I set it as updated. If not exist I set it as insert

public void AddOrUpdate(TEntity entity, Expression<Func<TEntity, bool>> predicate)
        {
            var oldEntity = Get(predicate);
            DetachEntry(oldEntity);

            if (oldEntity != null)
            {
                var idProperty = entity.GetType().GetProperties().First(x => x.Name == "Id");
                idProperty.SetValue(entity, idProperty.GetValue(oldEntity, null));

                Update(entity);
            }
            else
                Add(entity);
        }

When I try simple entity It works fine. But when I use very complex type I get following exception.

Database operation expected to affect 1 row(s) but actually affected 50 row(s). Data may have been modified or deleted since entities were loaded. See http://go.microsoft.com/fwlink/?LinkId=527962 for information on understanding and handling optimistic concurrency exceptions.

My complex type is like this.

public class FamilyMemberInfo 
    {

        public int Id { get; set; }

        public int AppealId { get; set; }

        public int MemberId { get; set; }

        public FamilyMember FamilyMember { get; set; }

        public Appeal Appeal { get; set; }

        public ICollection<FamilyMemberContact> Contacts { get; set; }

        public ICollection<FamilyMemberCrime> Crimes { get; set; }

        public ICollection<FamilyMemberDisease> Diseases { get; set; }

        public ICollection<FamilyMemberPaymentLiability> PaymentLiabilities { get; set; }


    }

After call AddOrUpdate method I look ChangeTraker every thing seem ok. And it generated very good query.

enter image description here enter image description here enter image description here enter image description here enter image description here

I can not find exception reason. I see familar errors on stakoverflow. But every solitions not work for me.

Edit

When I comment two child entities(it is not important which ones) everythink works fine

Babək
  • 23
  • 1
  • 9
  • Usually to avoid concurrency issue, you add a rowversion column to the table. https://learn.microsoft.com/en-us/sql/t-sql/data-types/rowversion-transact-sql You retreive it with the rest of the row data. You keep it around, usually never showing it to the user. Then when writing back the changes to see if the rowversion was changed by anyone else, as the last check. You know, after primary keys and everything else. It sounds like you tried to implement your own client level version of rowversion, and failed. – Christopher Oct 22 '19 at 12:02
  • That you even affect more then 1 row, clearly shows that either the query did not include the pimary key. Or something is really messed up with your primary keys, resulting in duplicates. Or maybe you are trying to write to the totally wrong table - on that uses said ID as a foreign key. Serious messups on the query level, that is for certain. – Christopher Oct 22 '19 at 12:04
  • @Christopher I set all primary keys in conficuration class. if you need to answer I can post all of them – Babək Oct 22 '19 at 12:08
  • @Christopher there is no one except me to change data on db – Babək Oct 22 '19 at 12:11
  • What is the primary key of the database table? A first name is not a primary key because many people have the same first name. Your query is using first name and then changing everybody in the table with the first name. Your query should be using a unique qualifier for the filter so you only change one person instead of multiple people. – jdweng Oct 22 '19 at 12:29
  • @jdweng primary key is not first name. My all entities have id. This id is primary key – Babək Oct 22 '19 at 12:33
  • Is Name an ID? var idProperty = entity.GetType().GetProperties().First(x => x.Name == "Id"); – jdweng Oct 22 '19 at 12:39
  • @jdweng on this line I find old entity id(property name is `Id`) value and set new entity id – Babək Oct 22 '19 at 13:03
  • You may have multiple crimes for the same person and that is why you are getting 50 rows changed. But then the ID has to be a primary key in both tables. Check the Database model to make sure all the tables that use ID are set to primary. All the list item tables should use the same primary ID. What is the difference between Id and MemberId? – jdweng Oct 22 '19 at 14:14
  • Id is primary key. MemberId is parent object id – Babək Oct 22 '19 at 14:26
  • @Babək: "there is no one except me to change data on db" If the end user just open the edit application/record modification window twice, they can still Update Race Condition themself. We know. It happens. A **lot**. Even the DBMS itself has to worry about concurrency. That is what all those implicit locks are for :) – Christopher Oct 23 '19 at 23:04
  • I read this is bug and I decided to change my project to .NetFramework – Babək Oct 24 '19 at 07:57

0 Answers0