none
STE I get object key values conflict exception, how to fix this simple code.

    Question

  • I get exception if i run the following code. Exception is

    AcceptChanges cannot continue because the object's key values conflict with another object in the ObjectStateManager. Make sure that the key values are unique before calling AcceptChanges.

    What is the proper way to write this code without the exception. Normally before I save a user I need to make sure that user already exists in the system or some other check, but I get exception if I call same user again. thanks. here is the code.

    // client call
    var client = new ChannelFactory<ISecurityService>("SecurityService").CreateChannel();
    var usr = client.GetUser(20);
    usr.Roles.Add(client.GetRole(1));
    client.SaveUser(usr);

    // service impl.

    public Role GetRole(int id)
    {
        using (var dc = new Fasttrak3Entities())
        {
            return dc.Roles.First(i => i.RoleId == id);
        }
    }
    public User GetUser(int id)
    {
        using (var dc = new Fasttrak3Entities())
        {
            return dc.Users.Include("Roles").First(i => i.UserId == id);
        }
    }
    public void SaveUser(User user)
    {
        using (var dc = new Fasttrak3Entities())
        {
            // exception occured due to this line..
            var ExistingUser = dc.Users.First(i => i.UserId == 20)
     
            // this line cause exception if I call above line.
            dc.Users.ApplyChanges(user);
            dc.SaveChanges();
        }
    }

    thanks

    ashraf.

    Wednesday, June 2, 2010 11:07 PM

Answers

  • Hi,

     

    The exception is thrown due to duplicate entity key tracked by the ObjectStateManager, since the existing user entity is loaded as well.   To check whether the certain entity exists at the database side, I suggest you modified the codes like this:

    ====================================================================

    if (dc.Users.Any(i => i.UserId = user.UserId))

    {

    dc.Users.ApplyChanges(user);

    dc.SaveChanges();

    }

    ====================================================================

    Here I used the .Any method to check if there is any User entity whose UserId equals the updated user’s UserId.  

     

    Hope it helps!

     

    Have a great day!

     

     

    Best Regards,
    Lingzhi Sun

    MSDN Subscriber Support in Forum

    If you have any feedback on our support, please contact msdnmg@microsoft.com


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    • Marked as answer by Ashraf TM Thursday, June 3, 2010 9:15 PM
    Thursday, June 3, 2010 3:31 AM
    Moderator
  • Yes, use a new context, when working with STEs and service calls the recomendation is to use short-live contexts.

    Alos, watch-out with the overuse of ".Any" as it can be expensive, see here for further details.

     


    -Jaime.
    • Marked as answer by Ashraf TM Thursday, June 3, 2010 9:13 PM
    Thursday, June 3, 2010 8:29 PM

All replies

  • Hi,

     

    The exception is thrown due to duplicate entity key tracked by the ObjectStateManager, since the existing user entity is loaded as well.   To check whether the certain entity exists at the database side, I suggest you modified the codes like this:

    ====================================================================

    if (dc.Users.Any(i => i.UserId = user.UserId))

    {

    dc.Users.ApplyChanges(user);

    dc.SaveChanges();

    }

    ====================================================================

    Here I used the .Any method to check if there is any User entity whose UserId equals the updated user’s UserId.  

     

    Hope it helps!

     

    Have a great day!

     

     

    Best Regards,
    Lingzhi Sun

    MSDN Subscriber Support in Forum

    If you have any feedback on our support, please contact msdnmg@microsoft.com


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    • Marked as answer by Ashraf TM Thursday, June 3, 2010 9:15 PM
    Thursday, June 3, 2010 3:31 AM
    Moderator
  • Hi,

     

    The exception is thrown due to duplicate entity key tracked by the ObjectStateManager, since the existing user entity is loaded as well.   To check whether the certain entity exists at the database side, I suggest you modified the codes like this:

     

    if (dc.Users.Any(i => i.UserId = user.UserId))

    {

    dc.Users.ApplyChanges(user);

    dc.SaveChanges();

    }


    Thanks Sun, Yes if I use "Any" I don't get entity so context won't track. But what if I need that entity object for other processing? Basically if I want that entity again in a query in the same context. I know I can use another context for retrieving information to avoid duplicate key. Any other workaround for the same context? If I use new context what would be the penalty?

    thanks ashraf.

    Thursday, June 3, 2010 3:57 PM
  • Yes, use a new context, when working with STEs and service calls the recomendation is to use short-live contexts.

    Alos, watch-out with the overuse of ".Any" as it can be expensive, see here for further details.

     


    -Jaime.
    • Marked as answer by Ashraf TM Thursday, June 3, 2010 9:13 PM
    Thursday, June 3, 2010 8:29 PM
  • Yes, use a new context, when working with STEs and service calls the recomendation is to use short-live contexts.

    Alos, watch-out with the overuse of ".Any" as it can be expensive, see here for further details.

     


    -Jaime.

     


    Thanks. Is it a bug or it is the behavior? Thanks for the “Any” overuse link.

    So better use 2 context (even if it is in same function); one for getting the entity and other for just saving entity nothing else.

     

    Thanks.

    Ashraf.

    Thursday, June 3, 2010 9:13 PM
  • Even with the short-lived contexts (for each and every single record!) I keep getting these and equivalent errors.
    I am at a loss here and am considering dropping EF altogether, unless something can be done about this issue.
    EF looked promising, but has brought me more pain than pleasure....

    Wednesday, July 7, 2010 9:12 AM
  • You cannot call ApplyChanges on an entity that is currently tracked in the ObjectContext. From what you describe, your scenario is fairly simple and that you need to check if the entity you are saving currently exist. What you can do is retrieving the User without going through the change tracking of the context by setting MergeOption.Notracking like below

    db.Users.MergeOption = MergeOption.NoTracking;

    db.Users.First(u => u.UserId == 1);

    db.Users.ApplyApplyChanges(user);

    db.SaveChanges();


    Zeeshan Hirani Entity Framework 4.0 Recipes by Apress
    http://weblogs.asp.net/zeeshanhirani
    Friday, July 30, 2010 3:13 PM