CustomerID jumps from 1 to 591 for only 8 registred users

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.
11 years ago
No I mean do a join of the Customer to the Customer_CustomerRole_Mapping table.  If they have a CustomerRole_Id of 4 (double check that it's Guest on your setup) then you don't follow through with the trigger.
11 years ago
My question is a bit tangential but I'll ask it anyways as it has to do with guest and converting them to Registered users.   I have written a custom controller to allow the submission of some information that includes an email address.  The other info is not related to the cart.  Will there be any issue if I take the _workContext.CurrentCustomer and if it is a guest to remove that role and add a couple other roles including Registered and ONLY setting the email and any other required field?  

I'm doing something like this and am wording if this will cause me any issues later on when they will need to pay for something?

Sample Code snippet:

if (customer.IsGuest(true))
            {
                //
               customer =   _customerService.GetCustomerByEmail(Project.email);
               if (customer == null)
               {
                   customer = _workContext.CurrentCustomer;
                   customer.Email = Project.email;
                   customer.LastActivityDateUtc = DateTime.UtcNow;
                   customer.CreatedOnUtc = DateTime.UtcNow;
                   customer.IsSystemAccount = false;
                   customer.Deleted = false;
                   customer.Active = true;
                   customer.UseRewardPointsDuringCheckout = false;
                   customer.IsTaxExempt = true;
                   customer.TaxDisplayType = 0;
                   customer.PasswordFormatId = 1;
                  
                
               }

               if (!customer.IsInCustomerRole("Project"))
               {
                   CustomerRole cr = _customerService.GetCustomerRoleBySystemName("Project");
                   customer.CustomerRoles.Add(cr);
               }
               if (!customer.IsInCustomerRole("Registered"))
               {
                   CustomerRole cr = _customerService.GetCustomerRoleBySystemName("Registered");
                   customer.CustomerRoles.Add(cr);
               }

               if (customer.IsInCustomerRole("Guests"))
               {
                   CustomerRole cr = _customerService.GetCustomerRoleBySystemName("Registered");
                    customer.CustomerRoles.Remove(cr);

               }

               _customerService.UpdateCustomer(customer);

            }
11 years ago
trying to enter new guest at the first empty id


public virtual Customer InsertGuestCustomer()
        {
            var customerIds = from c in _customerRepository.Table
                        orderby c.Id
                        select c.Id;

            int customerNextEmptyId = (
                from n in customerIds
                where !customerIds.Select(nu => nu).Contains(n + 1)
                orderby n
                select n + 1
            ).First();

     then insert the customer to the customerNextEmptyId


i cant find a way to SET IDENTITY_INSERT Customers ON

anyone ?
11 years ago
hezyz wrote:
trying to enter new guest at the first empty id


public virtual Customer InsertGuestCustomer()
        {
            var customerIds = from c in _customerRepository.Table
                        orderby c.Id
                        select c.Id;

            int customerNextEmptyId = (
                from n in customerIds
                where !customerIds.Select(nu => nu).Contains(n + 1)
                orderby n
                select n + 1
            ).First();

     then insert the customer to the customerNextEmptyId


i cant find a way to SET IDENTITY_INSERT Customers ON

anyone ?


Don't worry about the Id, just insert a customer and you will get the next Id.
11 years ago
AndyMcKenna wrote:


Don't worry about the Id, just insert a customer and you will get the next Id.


hi Andy

I am worried about the id, I want to enter the guest customer at the first empty (deleted) id


public virtual Customer InsertGuestCustomer()
        {
            //custom code
            var customerIds = from c in _customerRepository.Table
                              orderby c.Id
                              select c.Id;

            int customerNextEmptyId = (
                from n in customerIds
                where !customerIds.Select(nu => nu).Contains(n + 1)
                orderby n
                select n + 1
            ).First();
            //end of custom code
            var customer = new Customer()
            {
                Id = customerNextEmptyId,  //custom code
                CustomerGuid = Guid.NewGuid(),
                Active = true,
                CreatedOnUtc = DateTime.UtcNow,
                LastActivityDateUtc = DateTime.UtcNow,
            };

            //add to 'Guests' role
            var guestRole = GetCustomerRoleBySystemName(SystemCustomerRoleNames.Guests);
            if (guestRole == null)
                throw new NopException("'Guests' role could not be loaded");
            customer.CustomerRoles.Add(guestRole);
            _customerRepository.Insert(customer);

            return customer;
        }


please see at the new Customer I force the Id
the thing is the entity passed to the Insert method get the forced id. I tried to override the Insert method, however I cant find a way to enter that record in a specific Id.
I    SET IDENTITY_INSERT Customers ON with no luck.

thanks for your help

BTW, My point is to enter customers at the deleted spots and not increase the customers Id's
11 years ago
I don't think that loading all customer identifiers in memomy is a good idea. I would better implement it as a stored procedure:

1. Insert a record into [Customer] record with a stored procedure. Put all ID calculation and IDENTITY_INSERT logic there
2. Return a customer record from this stored procedure
3. Use this record in application to assign it to Guest customer role and any other logic

P.S. There's one more solution. But it'll require much more core changes. Do not use ID column in Customer table and make CustomerGuid as a primary key
11 years ago
@hezyz

Consider using the same logic as what's in DeleteGuestCustomers() to find your first "deleted" customer.  The only concern would be that the find and the subsequent update are not transactional - if multiple customers are registering at the "exact same time" , it would be a problem. (i.e. before you can update record with new LastActivityDateUtc.   See the 'last activity "prior" ' clause)

public virtual Customer GetGuestCustomerToReuse()
{
       var guestRole = GetCustomerRoleBySystemName(SystemCustomerRoleNames.Guests);
       if (guestRole == null)
           throw new NopException("'Guests' role could not be loaded");

        var query = _customerRepository.Table;
  query = query.Where(c => c.CustomerRoles.Select(cr => cr.Id).Contains(guestRole.Id));
  //last activity "prior"
  var priorActivity = DateTime.Now.AddDays(-1);
  query = query.Where(c => c.LastActivityDateUtc <= priorActivity );        
  //without shopping cart
  query = query.Where(c => c.ShoppingCartItems.Count() == 0);
  //no orders
  query = query.Where(c => c.Orders.Count() == 0);
  //no customer content
  query = query.Where(c => c.CustomerContent.Count() == 0);
  //ensure that customers doesn't have forum posts or topics
  query = query.Where(c => c.ForumTopics.Count() == 0);
  query = query.Where(c => c.ForumPosts.Count() == 0);
  //don't delete system accounts
  query = query.Where(c => !c.IsSystemAccount);
  
  var customer = query.FirstOrDefault();
}


Then, it's an easy modification to existing InsertGuestCustomer()


        public virtual Customer InsertGuestCustomer()
        {
            var customer = GetGuestCustomerToReuse();
            if (customer != null)
            {
                 customer.CreatedOnUtc = DateTime.UtcNow;
                 customer.LastActivityDateUtc = DateTime.UtcNow;
                 //?? update anything else ??
                  _customerRepository.Update(customer);
                 return customer
            }


            customer = new Customer()
            {
                CustomerGuid = Guid.NewGuid(),
                Active = true,
                CreatedOnUtc = DateTime.UtcNow,
                LastActivityDateUtc = DateTime.UtcNow,
            };

            //add to 'Guests' role
            var guestRole = GetCustomerRoleBySystemName(SystemCustomerRoleNames.Guests);
            if (guestRole == null)
                throw new NopException("'Guests' role could not be loaded");
            customer.CustomerRoles.Add(guestRole);

            _customerRepository.Insert(customer);

            return customer;
        }



(P.S.  Yes, this won't patch the existing holes, but it will stop the bleed :)
11 years ago
hezyz wrote:

I am worried about the id, I want to enter the guest customer at the first empty (deleted) id


Sorry, I misunderstood.
11 years ago
New York wrote:

The only concern would be that the find and the subsequent update are not transactional


That is what i'm worried about.

last night I thought on a different approach what if i will create a new duplicate customer table called GuestCustomer and insert all guest to that table. then the delete task can drop and create the table or set Identity to 0

before i start working, what do u think guys?


P.S we can trough to that new table the fake google registered as well.
for now i have restricted company = google from registration. i let the the registration process to complete I just do not execute the insert command. I though i can insert the fake accounts to the new table for monitoring.
11 years ago
Out of curiousity, what is your highest customer ID and how much does it go up each day?
This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.