The relationship between the two objects cannot be defined because they are attached to different ObjectContext objects

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.
11 years ago
Hi, I get the exception above and I'm not able to find where I am wrong; could any one help me please?

I get the nopProduct with ProductService and productTags with ProductTagService; it seems they are belonging to different object contexts, why?


                            if (nopProduct != null)
                            {
                                var existingProductTags = nopProduct.ProductTags.ToList();
                                if (!string.IsNullOrEmpty(product.TagsEn))
                                {
                                    string[] productTags = product.TagsEn.Split(STRING_SEPARATOR);
                                    var productTagsToDelete = new List<ProductTag>();
                                    foreach (var existingProductTag in existingProductTags)
                                    {
                                        bool found = false;
                                        foreach (string newProductTag in productTags)
                                        {
                                            if (existingProductTag.Name.Equals(newProductTag, StringComparison.InvariantCultureIgnoreCase))
                                            {
                                                found = true;
                                                break;
                                            }
                                        }
                                        if (!found)
                                        {
                                            productTagsToDelete.Add(existingProductTag);
                                        }
                                    }
                                    foreach (var productTag in productTagsToDelete)
                                    {
                                        nopProduct.ProductTags.Remove(productTag);
                                        //ensure product is saved before updating totals
                                        productService.UpdateProduct(nopProduct);
                                        productTagService.UpdateProductTagTotals(productTag);
                                    }

                                    foreach (string productTagName in productTags)
                                    {
                                        ProductTag productTag = null;
                                        var productTag2 = productTagService.GetProductTagByName(productTagName);
                                        if (productTag2 == null)
                                        {
                                            //add new product tag
                                            productTag = new ProductTag()
                                            {
                                                Name = productTagName,
                                                ProductCount = 0
                                            };
                                            productTagService.InsertProductTag(productTag);
                                        }
                                        else
                                        {
                                            productTag = productTag2;
                                        }
                                        if (!nopProduct.ProductTags.Any(x => x.Id.Equals(productTag.Id)))
                                        {
                                            nopProduct.ProductTags.Add(productTag); //AT THIS POINT I GET THE EXCEPTION
                                            //ensure product is saved before updating totals
                                            productService.UpdateProduct(nopProduct);
                                        }
                                        //update product tag totals
                                        productTag2 = productTagService.GetProductTagByName(productTagName);
                                        productTagService.UpdateProductTagTotals(productTag2);
                                    }
8 years ago
I recently had the same problem when adding a new customer with a customer role, in a plugin. Here is the code:

var nopCustomer = new Customer
{
    Username = customer.Email,
    Email = customer.Email,
    AffiliateId = affiliateId.HasValue ? affiliateId.Value : 0,
    Active = true,
    CustomerGuid = Guid.NewGuid(),
    CreatedOnUtc = DateTime.UtcNow,
    LastActivityDateUtc = DateTime.UtcNow,
};

// add the new customer into the guest role
var guestRole = _customerService.GetCustomerRoleBySystemName(SystemCustomerRoleNames.Guests);
nopCustomer.CustomerRoles.Add(guestRole);

_customerService.InsertCustomer(nopCustomer);


The problem for me was that the guest customer role was cached, and already attached to the guest customer the Nop platform automatically creates. So I just needed to replace this:

var guestRole = _customerService.GetCustomerRoleBySystemName(SystemCustomerRoleNames.Guests);


with this:

var guestRole = _customerService.GetAllCustomerRoles(true).FirstOrDefault(cr => cr.SystemName == SystemCustomerRoleNames.Guests);


For a more detailed explanation you can read this article (point 6 is talking about this problem).
7 years ago
I am getting the same error.  Posted my finding over on this thread, but wanted to bump here also to see if the community or nop dev can get an answer to this.

https://www.nopcommerce.com/boards/t/22472/associating-producttags-to-products.aspx
7 years ago
Anyone have any insight on this problem?  I am just overriding the CustomerRegistrationResult RegisterCustomer to do a check on the password (enforcing password complexity).  If the password is secure enough, we shoot the request on to the base class to register the user.


        public override CustomerRegistrationResult RegisterCustomer(CustomerRegistrationRequest request)
        {
            var result = new CustomerRegistrationResult();

            if (EvalPasswordComplexity(request.Password))
            {
                result = base.RegisterCustomer(request);
            }
            else
            {
                result.AddError("Could not register with provided password.");
            }

            return result;
        }


The relationship between the two objects cannot be defined because they are attached to different ObjectContext objects

Error occurs in Nop.Services - GenericAttributeService


public virtual void InsertAttribute(GenericAttribute attribute)
        {
            if (attribute == null)
                throw new ArgumentNullException("attribute");

// Error is on this line...
            _genericAttributeRepository.Insert(attribute);
            
            //cache
            _cacheManager.RemoveByPattern(GENERICATTRIBUTE_PATTERN_KEY);

            //event notification
            _eventPublisher.EntityInserted(attribute);
        }




Also to note, we overrode the ChangePasswordResult ChangePassword method...and this works fine (updated password is saved to the db).


        public override ChangePasswordResult ChangePassword(ChangePasswordRequest request)
        {
            if (request == null)
                throw new ArgumentNullException("request");

            var result = new ChangePasswordResult();

            if (EvalPasswordComplexity(request.NewPassword))
            {
                result = base.ChangePassword(request);
            }
            else
            {
                result.AddError("Could not register with provided password.");
            }

            return result;
        }
7 years ago
Saw this posting...not sure if it's accurate.

Is the RegisterUser considered a task, and thus even though my service has a context, when shooting this off to the base, it is thinking it's a different context?  If so, why isn't the change password bombing?  I assume register user is an insert, where change password is an update.


macbeth wrote:
uhm... is it possible detach an entity from the ObjectContext ?

For some reasons , when executed as a task by nopcommerce task manager, every service looks like belong to a different ObjectContext....


https://www.nopcommerce.com/boards/t/19175/strange-task-behaviour.aspx
7 years ago
More info....

Stepped through the code and found the exact line where the error is being thrown.  The RegisterCustomer service works and returns fine.  Then the code drops back into Nop.Web -> CustomerController -> HttpPost ActionResult REGISTER.

Down on the //form fields section, the error occurs on:


_genericAttributeService.SaveAttribute(customer, SystemCustomerAttributeNames.FirstName, model.FirstName);


Can anyone explain why...or more importantly, how to get a work around?
7 years ago
Sent a support ticket to nopCommerce folks, and they got me an answer super fast.  In my DependencyRegistrar, I had originally registered my service like this...

            // register service
            builder.RegisterType<MyCustomCustomerRegistrationService >()
                .As<ICustomerRegistrationService>()
                .InstancePerLifetimeScope();


...but since it was bombing I changed to this, just to see if I could get it working...

builder.RegisterType<MyCustomCustomerRegistrationService >()
                       .As<ICustomerRegistrationService>()
                       .SingleInstance()
                       .PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies);


...but it didn't help.  Still got the "attached to different ObjectContext objects" error.

The solution from nopCommerce Team :
"Entity Franework doesn't support second-level caching. But you had a single instance of MyCustomCustomerRegistrationService (hence datacontext was created only once). "

...so I should have stuck with using

builder.RegisterType<MyCustomCustomerRegistrationService >()
.As<ICustomerRegistrationService>()
.InstancePerLifetimeScope();


BUT IN ADDITION TO REGISTERING InstancePerLifetimeScope.....
"P.S. You have to set "Copy local" property of EntityFramework.dll and EntityFramework.SqlServer.dll references to "False""

Once I did BOTH (switch back register code and fix copy local on the referenced dlls), then the CustomerController - Register action was able to complete without error.
This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.