Associating ProductTags to Products

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.
11 лет назад
Hello!

I am developing a scheduled task that will periodically read data from a file in order to insert new products
into the database.

When reading the products from the file, the task will check and see if the product's tags (which are also in the file) have already been inserted previously, and in that case, the task should only create a new association between the new product and the existing tag.

The following code represents that part of the task's functionality:

                              // the product has been created previously on the cycle, by using productService.InsertProduct
                               NopEntities.Product theProduct = _productService.GetProductById(productId);

        foreach (string pTag in ArrayOfTags)
        {
          if (!string.IsNullOrWhiteSpace(pTag))
          {
            // check to see if the associated tag already exists
            NopEntities.ProductTag newTag = null;  // initialization
            NopEntities.ProductTag existingTag = _productTagService.GetProductTagByName(pTag);
            
            if (existingTag == null)
            {
              // then the tag does not exist yet. Create a new one
              newTag = new NopEntities.ProductTag();
              newTag.Name = pTag;
              newTag.ProductCount = 1;
            }
            else
            {
              newTag = existingTag;
            }

            // associate the product with the new tag
            theProduct.ProductTags.Add(newTag);
            _productService.UpdateProduct(theProduct);
          }
        }


The product is always inserted by using _productService.InsertProduct previously.

The code works as expected if the tag does not exist in the database.
However, if the tag already exists, I get the following exception:

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

Can you tell me what I am doing wrong?

Thank you,
André.
11 лет назад
Hello?

Can someone help me please?...
8 лет назад
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).
8 лет назад
same problem cannot add product tags anyone to help?
7 лет назад
We are getting the same error on Nop 3.8.  I looked at the framework for our plugin and nop.web. nop.data, nop.admin, and all are using 4.5.1.  I also checked to ensure all the projects were using the same reference dlls, which they were.

Ours is a plugin that extends password complexity and locks an account after N number of incorrect login attempts.  Here is the dependency registrar file.  We are checking the plugin to see if it's installed before we do anything (my co-worker said he found an issue that the site would sometimes pick it up and do something even if it wasn't installed yet).

public virtual void Register(ContainerBuilder builder, ITypeFinder typeFinder, NopConfig config)
        {
            //Is this plugin installed??
            var isInstalled = false;
            var types = typeFinder.FindClassesOfType<IPluginFinder>(true);
            if (types.Count() == 1)
            {
                var plugins = Activator.CreateInstance(types.First()) as IPluginFinder;
                var plug = plugins.GetPluginDescriptorBySystemName("Ingram.Security");

                if (plug != null && plug.Installed)
                {
                    isInstalled = true;
                }
            }

            // Overriden customer registration service
            if (isInstalled)
            {
                builder.RegisterType<IngCustomerRegistrationService>()
                       .As<ICustomerRegistrationService>().SingleInstance()
                       .PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies);

                //data context
                this.RegisterPluginDataContext<LogInAttemptRecordObjectContext>(builder, CONTEXT_NAME);

                //override required repository with our custom context
                builder.RegisterType<EfRepository<LogInAttemptRecord>>()
                    .As<IRepository<LogInAttemptRecord>>()
                    .WithParameter(ResolvedParameter.ForNamed<IDbContext>(CONTEXT_NAME))
                    .InstancePerLifetimeScope();
            }
        }


In the CustomerRegistrationServiceExtension class, here is the override on RegisterCustomer...


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;

            // Initially took out all code and just ran the base, but still got the error.  
            // Only works if the plugin is not installed.
            //return base.RegisterCustomer(request);
        }


Here is the error...
Server Error in '/Nop' Application.

The relationship between the two objects cannot be defined because they are attached to different ObjectContext objects.
  Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.InvalidOperationException: The relationship between the two objects cannot be defined because they are attached to different ObjectContext objects.

Source Error:


The source code that generated this unhandled exception can only be shown when compiled in debug mode. To enable this, please follow one of the below steps, then request the URL:

1. Add a "Debug=true" directive at the top of the file that generated the error. Example:

   <%@ Page Language="C#" Debug="true" %>

or:

2) Add the following section to the configuration file of your application:

<configuration>
    <system.web>
        <compilation debug="true"/>
    </system.web>
</configuration>

Note that this second technique will cause all files within a given application to be compiled in debug mode. The first technique will cause only that particular file to be compiled in debug mode.

Important: Running applications in debug mode does incur a memory/performance overhead. You should make sure that an application has debugging disabled before deploying into production scenario.  

Stack Trace:



[InvalidOperationException: The relationship between the two objects cannot be defined because they are attached to different ObjectContext objects.]
   System.Data.Entity.Core.Objects.DataClasses.RelatedEnd.ValidateContextsAreCompatible(RelatedEnd targetRelatedEnd) +447
   System.Data.Entity.Core.Objects.DataClasses.RelatedEnd.Add(IEntityWrapper wrappedTarget, Boolean applyConstraints, Boolean addRelationshipAsUnchanged, Boolean relationshipAlreadyExists, Boolean allowModifyingOtherEndOfRelationship, Boolean forceForeignKeyChanges) +210
   System.Data.Entity.Core.Objects.ObjectStateManager.PerformAdd(IEntityWrapper wrappedOwner, RelatedEnd relatedEnd, IEntityWrapper entityToAdd, Boolean isForeignKeyChange) +510
   System.Data.Entity.Core.Objects.ObjectStateManager.PerformAdd(IList`1 entries) +970
   System.Data.Entity.Core.Objects.ObjectStateManager.DetectChanges() +163
   System.Data.Entity.Internal.InternalContext.DetectChanges(Boolean force) +39
   System.Data.Entity.Internal.Linq.InternalSet`1.ActOnSet(Action action, EntityState newState, Object entity, String methodName) +107
   System.Data.Entity.Internal.Linq.InternalSet`1.Add(Object entity) +171
   System.Data.Entity.DbSet`1.Add(TEntity entity) +113
   Nop.Data.EfRepository`1.Insert(T entity) +326
   Nop.Services.Common.GenericAttributeService.InsertAttribute(GenericAttribute attribute) in C:\Users\jonathan.spencer\Documents\Visual Studio 2015\Projects\nopCommerce\src\Libraries\Nop.Services\Common\GenericAttributeService.cs:124
   Nop.Services.Common.GenericAttributeService.SaveAttribute(BaseEntity entity, String key, TPropType value, Int32 storeId) in C:\Users\jonathan.spencer\Documents\Visual Studio 2015\Projects\nopCommerce\src\Libraries\Nop.Services\Common\GenericAttributeService.cs:225
   Nop.Web.Controllers.CustomerController.Register(RegisterModel model, String returnUrl, Boolean captchaValid, FormCollection form) +3262
   lambda_method(Closure , ControllerBase , Object[] ) +298
   System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +229
   System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +35
   System.Web.Mvc.Async.AsyncControllerActionInvoker.<BeginInvokeSynchronousActionMethod>b__39(IAsyncResult asyncResult, ActionInvocation innerInvokeState) +39
   System.Web.Mvc.Async.WrappedAsyncResult`2.CallEndDelegate(IAsyncResult asyncResult) +71
   System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) +42
   System.Web.Mvc.Async.AsyncInvocationWithFilters.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3d() +72
   System.Web.Mvc.Async.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f() +386
   System.Web.Mvc.Async.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f() +386
   System.Web.Mvc.Async.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f() +386
   System.Web.Mvc.Async.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f() +386
   System.Web.Mvc.Async.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f() +386
   System.Web.Mvc.Async.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f() +386
   System.Web.Mvc.Async.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f() +386
   System.Web.Mvc.Async.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f() +386
   System.Web.Mvc.Async.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f() +386
   System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult) +42
   System.Web.Mvc.Async.<>c__DisplayClass2b.<BeginInvokeAction>b__1c() +38
   System.Web.Mvc.Async.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult) +186
   System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +38
   System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState) +29
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +67
   System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +53
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +36
   System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +38
   System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState) +44
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +67
   System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +38
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +399
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +137

  


Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.6.1087.0  
7 лет назад
BTW...this 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);
        }




....and yes, all the references and framework versions match up in Nop.Services to the plugin stuff.
This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.