Adding a new table or a field to existing table n NopCommerce 4.3

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.
Il y a 3 ans
Hi, I know there are existing topics and answered questions about adding a new field or tablet o nopcommerce database. But since version 4.3, migration is automatically embedded to nopcommerce, also Mysql database is supported and entity microsoft entity framework is abondened. The model files are also different in version 4.3. There are no .hasKey, [Required], hasMaxlength() etc. I am a programmer in MVC but not an expert. I am not a master of ORM’s, only acquinted with Microsoft Entity Framework.
My questions are: 1. How a new field is added to n existing Entity, for example Customer Entity a new string field called IdentityNumber of maxlegth(11) and a required field?
2. How will be the add migration and update-database?
Thank you in advance
Il y a 3 ans
If you do want just want to add a new field for a customer then you can use Custom customer attributes
See in yourwebsite.com/Admin/Setting/CustomerUser
Add a new Custom customer attributes then it will be displayed in the register form and in their  Account
Il y a 3 ans
Thank you Yidna for your quick reply. I saw we could add custom attribute to Customer table but how will we refer to that attribute value in the code? In Turkey, Personel Identification Number (a unique Id given to each individual by Government) is compulsory in Credit Card Payments and in payment plugin we must provide it.
Also, there is not possibility of adding custom attribute for every table as far as I can see in NopCommerce. I want to know the steps for adding a field to existing table in NopCommerce if anyone can provide.
In NopCommerce 4.2, there was Microsoft Entity Framework but migration was not ready to work with. Woon Cherk Lam (thanks to him) described step by step adding code-first-migrations but it was for before NopCommerce 4.2 and the code is for old versions I think.
https://www.pronopcommerce.com/using-entity-framework-ef-code-first-migrations-in-nopcommerce-for-fast-customizations.
There is a need for a general guide for adding a new table or field for nopcommerce version 4.3 and later.
Any help will be appreciated. Thank you very much.
Il y a 3 ans
General approach to extend data schema codebase (non plugin approach) in 4.3 is:

1) In Nop.Core, extend the Domain model. This can be in your own .cs file for code separation, but match the namespace to the nopCommerce domain. it this example Nop.Core.Domain.Catalog


namespace Nop.Core.Domain.Catalog
{
    public partial class Category
    {
        /// <summary>
        /// Gets or sets the MyNewPropertyForCategory
        /// </summary>
        public string MyNewPropertyForCategory { get; set; }
    }
}


2) In Nop.Data, Add any fluent characteristics required to your new property in the Builder. In this example Nop.Data.Mapping.Builders.Catalog.CategoryBuilder.cs - Note: I have not found a way to separate this code out into its own file


using FluentMigrator.Builders.Create.Table;
using Nop.Core.Domain.Catalog;

namespace Nop.Data.Mapping.Builders.Catalog
{
    /// <summary>
    /// Represents a category entity builder
    /// </summary>
    public partial class CategoryBuilder : NopEntityBuilder<Category>
    {
        #region Methods

        /// <summary>
        /// Apply entity configuration
        /// </summary>
        /// <param name="table">Create table expression builder</param>
        public override void MapEntity(CreateTableExpressionBuilder table)
        {
            table
                .WithColumn(nameof(Category.Name)).AsString(400).NotNullable()
                .WithColumn(nameof(Category.MetaKeywords)).AsString(400).Nullable()
                .WithColumn(nameof(Category.MetaTitle)).AsString(400).Nullable()
                .WithColumn(nameof(Category.PriceRanges)).AsString(400).Nullable()
                .WithColumn(nameof(Category.PageSizeOptions)).AsString(200).Nullable()

// ## Your new property here

     .WithColumn(nameof(Category.MyNewPropertyForCategory )).AsString(100).Nullable();

//###

        }

        #endregion
    }
}



If you create the field in the db manually, then this will just work.

The migrations to add a field.. I am still trying to work this out!




asenol70 wrote:
Thank you Yidna for your quick reply. I saw we could add custom attribute to Customer table but how will we refer to that attribute value in the code? In Turkey, Personel Identification Number (a unique Id given to each individual by Government) is compulsory in Credit Card Payments and in payment plugin we must provide it.
Also, there is not possibility of adding custom attribute for every table as far as I can see in NopCommerce. I want to know the steps for adding a field to existing table in NopCommerce if anyone can provide.
In NopCommerce 4.2, there was Microsoft Entity Framework but migration was not ready to work with. Woon Cherk Lam (thanks to him) described step by step adding code-first-migrations but it was for before NopCommerce 4.2 and the code is for old versions I think.
https://www.pronopcommerce.com/using-entity-framework-ef-code-first-migrations-in-nopcommerce-for-fast-customizations.
There is a need for a general guide for adding a new table or field for nopcommerce version 4.3 and later.
Any help will be appreciated. Thank you very much.
Il y a 3 ans
Thank you very much JonQuick, actually I added the new field in Customer.cs but I think your way of putting it another file as a partial class is better. I also found the below class and added field attributes as you mentioned in your reply.  
public partial class CategoryBuilder : NopEntityBuilder<Category>
But I can't see where is the primary key definition for Customer table? Is is all about the field definitions of Customer table in this file?(in addition to Customer.cs of course)
You say, if I add the new column in database, it will work. I will try and write result here.
It would be better if it were done by code-first and migration approach.
Thank you again for your kindness.
Il y a 3 ans
I have not had time yet to get deep into the new architecture with Linq2db and migrations. Some assumptions I have concluded:

The PK is setup for you auto-magically, when a Domain class such as Product or Category  is inherited from BaseEntity (which has an Id property). The code-first mapping to Db will set the Id property up as PK.

Foreign key is defined explicitly in the Builder class. Here is an example of FK CustomerId in the OrderBuilder class


.WithColumn(nameof(Order.CustomerId)).AsInt32().ForeignKey<Customer>(onDelete: Rule.None)


asenol70 wrote:
Thank you very much JonQuick, actually I added the new field in Customer.cs but I think your way of putting it another file as a partial class is better. I also found the below class and added field attributes as you mentioned in your reply.  
public partial class CategoryBuilder : NopEntityBuilder<Category>
But I can't see where is the primary key definition for Customer table? Is is all about the field definitions of Customer table in this file?(in addition to Customer.cs of course)
You say, if I add the new column in database, it will work. I will try and write result here.
It would be better if it were done by code-first and migration approach.
Thank you again for your kindness.
Il y a 3 ans
Thank you JonQuick.
Now I will share my efforts for adding a column to Customer table in NopCommerce version 4.3

I added the folowing line to Customer.cs

  public String IdentityNumber { get; set; }


I added a line in following file
  ~nopc43\Libraries\Nop.Data\Mapping\Builders\Customers\CustomerBuilder.cs
        public override void MapEntity(CreateTableExpressionBuilder table)
        {
            table
                .WithColumn(nameof(Customer.Username)).AsString(1000).Nullable()
...
                .WithColumn(nameof(Customer.IdentityNumber)).AsString(11).NotNullable()  // that is the line I added
  

Then in SSMS (my database was in Sql Server) I added a column IdentityNumber as nVarchar(11) to Customer Table
I updated value in the column IdentityNumber in the rows of the table

In paymentService...cs file, customerName, customerSurName came from database well but customerIdentityNumber came null from database although it was not null
    var customer = _customerService.GetCustomerById(customerId);
  .....
  var customerName = _genericAttributeService.GetAttribute<string>(customer, NopCustomerDefaults.FirstNameAttribute);
    var customerSurName = _genericAttributeService.GetAttribute<string>(customer, NopCustomerDefaults.LastNameAttribute);
    var customerIdentityNumber = _genericAttributeService.GetAttribute<string>(customer, "IdentityNumber");
      
      
In file
~nopc43\Libraries\Nop.Core\Domain\Customers\NopCustomerDefaults.cs
      
I added the following line
        public static string EuCookieLawAcceptedAttribute => "EuCookieLaw.Accepted";  // this line was present before. I added the line after this line
        public static string IdentityNumberAttribute => "IdentityNumber";      // this line is the one I inserted
    
I ran after this change but again   customerIdentityNumber came as null  
    var customerIdentityNumber = _genericAttributeService.GetAttribute<string>(customer, "IdentityNumber");
  
I then changed the line as
  var customerIdentityNumber =  customer.IdentityNumber;

This time   customerIdentityNumber got the value from database.It worked.

But I didn't understand why << _genericAttributeService.GetAttribute<string>(customer, "IdentityNumber"); >> didn't work.
Il y a 3 ans
asenol70 wrote:
...I then changed the line as
  var customerIdentityNumber =  customer.IdentityNumber;

This time   customerIdentityNumber got the value from database.It worked.

But I didn't understand why << _genericAttributeService.GetAttribute<string>(customer, "IdentityNumber"); >> didn't work.

Because you added a column to the Customer table.  The GenericAttribute table is a separate table.  You can extend customer properties by using one or the other, but not both for the same property.
Il y a 3 ans
I would write "You are right but Customer FirstName and LastName are also not custom attributes but they came from the database successfully" but I recognised Customer table do not have FirstName and LastName attributes. They were custom attributes also.
I didn't write payment plugin myself and found the code in Github (Emre Küçük's Iyzico payment plugin)  so I didn't realize it.
Thank you NewYork.
Il y a 3 ans
When I look into original source code downloaded from nopcommerce version 4.3
There is a file NopCustomerDefaults.cs. In the file FirstName and LastName are defined as generic attributes.
But they are not custom attributes (they are not defined by person using nopcommerce admin panel), and also they are not fields (columns) of Customer table.
Then where on earth they are tied to database? Where do the following code get data from (a code line of payment plugin)?

var customerName = _genericAttributeService.GetAttribute<string>(customer, NopCustomerDefaults.FirstNameAttribute);



nopc43\Libraries\Nop.Core\Domain\Customers\NopCustomerDefaults.cs

    #region Customer attributes

        /// <summary>
        /// Gets a name of generic attribute to store the value of 'FirstName'
        /// </summary>
        public static string FirstNameAttribute => "FirstName";

        /// <summary>
        /// Gets a name of generic attribute to store the value of 'LastName'
        /// </summary>
        public static string LastNameAttribute => "LastName";

        /// <summary>
        /// Gets a name of generic attribute to store the value of 'Gender'
        /// </summary>
        public static string GenderAttribute => "Gender";



When I look at http://localhost:15536/Admin/Setting/CustomerUser in admin panel of nopcommerce, there is no custom attribute defined for customer.
Also in SSMS, no rows returned from the query below
SELECT [Id] ,[Name],[IsRequired] ,[AttributeControlTypeId] ,[DisplayOrder]
  FROM [nopcom].[dbo].[CustomerAttribute]

  
What is the purpose of  NopCustomerDefaults.cs file?
This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.