diff --git a/src/Libraries/Nop.Data/Extensions/FluentMigratorExtensions.cs b/src/Libraries/Nop.Data/Extensions/FluentMigratorExtensions.cs
index 81f9d6f88f8..ea2bbfcb572 100644
--- a/src/Libraries/Nop.Data/Extensions/FluentMigratorExtensions.cs
+++ b/src/Libraries/Nop.Data/Extensions/FluentMigratorExtensions.cs
@@ -1,9 +1,17 @@
using System.ComponentModel.DataAnnotations.Schema;
using System.Data;
+using System.Linq.Expressions;
using System.Reflection;
+using FluentMigrator.Builders;
+using FluentMigrator.Builders.Alter;
using FluentMigrator.Builders.Alter.Table;
using FluentMigrator.Builders.Create;
using FluentMigrator.Builders.Create.Table;
+using FluentMigrator.Builders.Delete;
+using FluentMigrator.Builders.Delete.Column;
+using FluentMigrator.Builders.Schema;
+using FluentMigrator.Builders.Schema.Column;
+using FluentMigrator.Builders.Schema.Table;
using FluentMigrator.Infrastructure.Extensions;
using FluentMigrator.Model;
using FluentMigrator.Runner;
@@ -63,7 +71,7 @@ private static void DefineByOwnType(string columnName, Type propType, CreateTabl
/// The builder to add the database engine(s) to
/// The migration runner builder
public static IMigrationRunnerBuilder AddNopDbEngines(this IMigrationRunnerBuilder builder)
- {
+ {
if (!DataSettingsManager.IsDatabaseInstalled())
return builder.AddSqlServer().AddMySql5().AddPostgres92();
@@ -145,6 +153,101 @@ public static void TableFor(this ICreateExpressionRoot expressionRoot)
builder.RetrieveTableExpressions(type);
}
+ ///
+ /// Targets the entity's mapped table for a DELETE operation.
+ ///
+ /// The root expression for a DELETE operation
+ /// The entity type mapped to the database table
+ public static void TableFor(this IDeleteExpressionRoot expressionRoot) where TEntity : BaseEntity
+ {
+ var tableName = NameCompatibilityManager.GetTableName(typeof(TEntity));
+ expressionRoot.Table(tableName);
+ }
+
+ ///
+ /// Targets the entity's mapped table for an ALTER TABLE operation.
+ ///
+ /// The root expression for an ALTER operation
+ /// The entity type mapped to the database table
+ ///
+ /// A fluent syntax interface allowing further ALTER TABLE operations
+ /// such as adding or modifying columns.
+ ///
+ public static IAlterTableAddColumnOrAlterColumnOrSchemaOrDescriptionSyntax TableFor(this IAlterExpressionRoot expressionRoot) where TEntity : BaseEntity
+ {
+ var tableName = NameCompatibilityManager.GetTableName(typeof(TEntity));
+ return expressionRoot.Table(tableName);
+ }
+
+ ///
+ /// Targets the entity's mapped table for schema-related operations.
+ ///
+ /// The root expression for schema inspection
+ /// The entity type mapped to the database table
+ ///
+ /// A fluent syntax interface for performing schema operations
+ /// such as checking table or column existence.
+ ///
+ public static ISchemaTableSyntax TableFor(this ISchemaExpressionRoot expressionRoot) where TEntity : BaseEntity
+ {
+ var tableName = NameCompatibilityManager.GetTableName(typeof(TEntity));
+ return expressionRoot.Table(tableName);
+ }
+
+ ///
+ /// Targets a specific column of the entity's mapped table for schema inspection,
+ /// resolving the column name via .
+ ///
+ /// The entity type mapped to the database table
+ /// The schema table expression
+ /// An expression selecting the entity property
+ ///
+ /// A fluent syntax interface for performing schema operations
+ /// such as checking column existence.
+ ///
+ public static ISchemaColumnSyntax ColumnFor(
+ this ISchemaTableSyntax tableSchema, Expression> selector) where TEntity : BaseEntity
+ {
+ var property = ((MemberExpression)selector.Body)?.Member?.Name;
+ var columnName = NameCompatibilityManager.GetColumnName(typeof(TEntity), property!);
+ return tableSchema.Column(columnName);
+ }
+
+ ///
+ /// Adds a new column to the entity's mapped table for ALTER TABLE operations,
+ /// resolving the column name via .
+ ///
+ /// The entity type mapped to the database table
+ /// The alter table expression
+ /// An expression selecting the entity property
+ ///
+ /// A fluent syntax interface allowing further ALTER TABLE operations
+ /// on the specified column.
+ ///
+ public static IAlterTableColumnAsTypeSyntax AddColumnFor(
+ this IAlterTableAddColumnOrAlterColumnSyntax tableSchema, Expression> selector) where TEntity : BaseEntity
+ {
+ var property = ((MemberExpression)selector.Body)?.Member?.Name;
+ var columnName = NameCompatibilityManager.GetColumnName(typeof(TEntity), property!);
+ return tableSchema.AddColumn(columnName);
+ }
+
+ ///
+ /// Targets the mapped table of the specified entity for a DELETE COLUMN operation,
+ /// resolving the table name via .
+ ///
+ /// The entity type mapped to the database table
+ /// The delete column expression from table syntax
+ ///
+ /// A fluent syntax interface allowing the deletion of columns from the specified table.
+ ///
+ public static IInSchemaSyntax FromTable(
+ this IDeleteColumnFromTableSyntax expressionRoot) where TEntity : BaseEntity
+ {
+ var tableName = NameCompatibilityManager.GetTableName(typeof(TEntity));
+ return expressionRoot.FromTable(tableName);
+ }
+
///
/// Retrieves expressions for building an entity table
///
diff --git a/src/Libraries/Nop.Data/Migrations/UpgradeTo490/SchemaMigration.cs b/src/Libraries/Nop.Data/Migrations/UpgradeTo490/SchemaMigration.cs
index 3e12547f59e..ab78faf6cd8 100644
--- a/src/Libraries/Nop.Data/Migrations/UpgradeTo490/SchemaMigration.cs
+++ b/src/Libraries/Nop.Data/Migrations/UpgradeTo490/SchemaMigration.cs
@@ -15,89 +15,93 @@ public class SchemaMigration : ForwardOnlyMigration
public override void Up()
{
//#7387
- var productTableName = nameof(Product);
-
- var ageVerificationColumnName = nameof(Product.AgeVerification);
- if (!Schema.Table(productTableName).Column(ageVerificationColumnName).Exists())
+ if (!Schema.TableFor().ColumnFor(t => t.AgeVerification).Exists())
{
- Alter.Table(productTableName)
- .AddColumn(ageVerificationColumnName)
+ Alter.TableFor()
+ .AddColumnFor(t => t.AgeVerification)
.AsBoolean()
.NotNullable()
.WithDefaultValue(false);
}
- var minimumAgeToPurchaseColumnName = nameof(Product.MinimumAgeToPurchase);
- if (!Schema.Table(productTableName).Column(minimumAgeToPurchaseColumnName).Exists())
+ if (!Schema.TableFor().ColumnFor(t => t.MinimumAgeToPurchase).Exists())
{
- Alter.Table(productTableName)
- .AddColumn(minimumAgeToPurchaseColumnName)
+ Alter.TableFor()
+ .AddColumnFor(t => t.MinimumAgeToPurchase)
.AsInt32()
.NotNullable()
.WithDefaultValue(0);
}
//#7294
- var topicTableName = nameof(Topic);
- var topicAvailableEndDateColumnName = nameof(Topic.AvailableEndDateTimeUtc);
- var topicAvailableStartDateColumnName = nameof(Topic.AvailableStartDateTimeUtc);
- if (!Schema.Table(topicTableName).Column(topicAvailableEndDateColumnName).Exists())
+ if (!Schema.TableFor().ColumnFor(t => t.AvailableEndDateTimeUtc).Exists())
{
- Alter.Table(topicTableName)
- .AddColumn(topicAvailableEndDateColumnName)
+ Alter.TableFor()
+ .AddColumnFor(t => t.AvailableEndDateTimeUtc)
.AsDateTime()
.Nullable();
}
- if (!Schema.Table(topicTableName).Column(topicAvailableStartDateColumnName).Exists())
+ if (!Schema.TableFor().ColumnFor(t => t.AvailableStartDateTimeUtc).Exists())
{
- Alter.Table(topicTableName)
- .AddColumn(topicAvailableStartDateColumnName)
+ Alter.TableFor()
+ .AddColumnFor(t => t.AvailableStartDateTimeUtc)
.AsDateTime()
.Nullable();
}
//#873
- var productTagTableName = nameof(ProductTag);
- if (!Schema.Table(productTagTableName).Column(nameof(ProductTag.MetaDescription)).Exists())
- Alter.Table(productTagTableName).AddColumn(nameof(ProductTag.MetaDescription)).AsString().Nullable();
+ if (!Schema.TableFor().ColumnFor(t => t.MetaDescription).Exists())
+ {
+ Alter.TableFor()
+ .AddColumnFor(t => t.MetaDescription)
+ .AsString()
+ .Nullable();
+ }
- if (!Schema.Table(productTagTableName).Column(nameof(ProductTag.MetaKeywords)).Exists())
- Alter.Table(productTagTableName).AddColumn(nameof(ProductTag.MetaKeywords)).AsString(400).Nullable();
+ if (!Schema.TableFor().ColumnFor(t => t.MetaKeywords).Exists())
+ {
+ Alter.TableFor()
+ .AddColumnFor(t => t.MetaKeywords)
+ .AsString(400)
+ .Nullable();
+ }
- if (!Schema.Table(productTagTableName).Column(nameof(ProductTag.MetaTitle)).Exists())
- Alter.Table(productTagTableName).AddColumn(nameof(ProductTag.MetaTitle)).AsString(400).Nullable();
+ if (!Schema.TableFor().ColumnFor(t => t.MetaTitle).Exists())
+ {
+ Alter.TableFor()
+ .AddColumnFor(t => t.MetaTitle)
+ .AsString(400)
+ .Nullable();
+ }
//#7390
- if (!Schema.Table(nameof(Menu)).Exists())
+ if (!Schema.TableFor