GoogleTag

Google Search

How to generate Database Migration script dynamically by using XML

 Generating migration scripts dynamically using XML offers several advantages, particularly in software development and database management. Here are the key reasons why this approach is beneficial:

1. Consistency and Automation

  • Automation: Dynamic generation of migration scripts through XML ensures that the migration process is automated. This reduces the manual effort and potential errors when creating migration scripts, leading to more efficient and reliable migrations.
  • Consistency: The XML structure can enforce consistency in the way migration scripts are generated, ensuring that every change in the database schema follows the same structure and methodology.

2. Version Control

  • Track Changes: XML files can be version-controlled, allowing teams to track changes in the schema over time. This is especially useful when working with teams or on larger projects, as it allows for easy comparison and rollback of changes.
  • Incremental Updates: Each migration generated through XML can include incremental changes, helping to maintain a smooth transition between database versions and preventing issues from arising when applying migrations.

3. Separation of Concerns

  • Decoupling: By using XML to define migration scripts, you separate the schema changes from the actual code that applies those changes. This makes it easier to manage and modify the database schema without touching the application codebase.
  • Clarity and Maintainability: XML can provide a clear and structured representation of schema changes, making it easier to read, update, and maintain the migration logic.

4. Cross-Platform Compatibility

  • Platform Independence: XML is a platform-independent format, making it easier to share migration scripts across different environments (e.g., development, staging, production). The XML can be used across different database systems with minimal changes, making the migration process more portable.

5. Customization and Flexibility

  • Dynamic Customization: By defining migration logic in XML, it becomes easier to customize how migration scripts are generated based on specific needs, such as altering table structures, adding indexes, or updating data.
  • Parameterization: You can parameterize the XML to adapt to different environments or configurations, making it possible to generate environment-specific migration scripts automatically.

6. Database Agnostic

  • Database Independence: The migration scripts generated from XML can be designed to be database-agnostic, allowing you to apply migrations across different database types (e.g., MySQL, PostgreSQL, SQL Server) with minimal adjustments.

7. Scalability

  • Managing Large Databases: In large-scale applications with many databases or complex schema changes, dynamically generating migration scripts through XML can help scale the process. It ensures that changes are applied in an organized manner across various environments, minimizing human intervention and errors.

8. Error Reduction

  • Eliminating Human Errors: Writing migration scripts manually can introduce human errors. By automating the process through XML generation, the likelihood of errors in the migration scripts is minimized, ensuring a smoother deployment process.

9. Auditability and Traceability

  • Audit Trails: Since XML files are typically stored and versioned, they provide an audit trail of what changes were made to the database schema and when, which is critical for tracking schema changes in regulated environments or large projects.

10. Easier to Manage Complex Changes

  • Handling Complex Migrations: XML allows you to handle complex migrations (e.g., multi-step schema changes, data transformations) by providing a structured way to define each step in the migration, making it easier to manage large or complicated database updates.

In summary, using XML for dynamically generating migration scripts provides better automation, consistency, and flexibility while reducing manual errors and making the process scalable and maintainable.

Generic template for a SQL Server migration script that includes key operations like schema changes, table migrations, and data transfer. You can customize it based on your database migration requirements.

Template: SQL Server Migration Script

-- Start of Migration Script

USE [YourDatabaseName];

GO

 

-- 1. BEGIN TRANSACTION

BEGIN TRANSACTION;

BEGIN TRY

 

    -- 2. BACKUP EXISTING TABLES (Optional Step for Safety)

    -- Backup Table Example:

    SELECT * INTO TableName_Backup_YYYYMMDD

    FROM TableName;

 

    -- 3. ADD NEW TABLE OR MODIFY SCHEMA

    -- Creating a new table

    CREATE TABLE NewTableName (

        Id INT PRIMARY KEY IDENTITY(1,1),

        Column1 NVARCHAR(50) NOT NULL,

        Column2 DATETIME DEFAULT GETDATE(),

        Column3 DECIMAL(10,2)

    );

 

    -- Adding a new column to an existing table

    ALTER TABLE ExistingTableName

    ADD NewColumnName NVARCHAR(100) NULL;

 

    -- Modifying a column type (ensure no conflicts)

    ALTER TABLE ExistingTableName

    ALTER COLUMN ColumnToModify NVARCHAR(255);

 

    -- 4. MIGRATE DATA TO NEW STRUCTURE

    -- Insert data into a new table

    INSERT INTO NewTableName (Column1, Column2, Column3)

    SELECT OldColumn1, OldColumn2, OldColumn3

    FROM OldTableName;

 

    -- 5. DATA CLEANUP (Optional)

    -- Delete unwanted data

    DELETE FROM OldTableName

    WHERE Condition;

 

    -- 6. DROP/RENAME OLD TABLES (IF REQUIRED)

    -- Rename old table

    EXEC sp_rename 'OldTableName', 'OldTableName_Archived';

 

    -- Drop old table

    -- DROP TABLE OldTableName;

 

    -- 7. COMMIT TRANSACTION

    COMMIT TRANSACTION;

    PRINT 'Migration completed successfully';

 

END TRY

BEGIN CATCH

    -- ROLLBACK IN CASE OF FAILURE

    ROLLBACK TRANSACTION;

    PRINT 'Error occurred during migration. Transaction rolled back.';

    PRINT ERROR_MESSAGE();

END CATCH;

GO

 

-- 8. VERIFICATION QUERIES (Optional)

SELECT * FROM NewTableName;

SELECT * FROM ExistingTableName;

Key Notes:

  1. Transaction Management:
    Using BEGIN TRANSACTION, COMMIT, and ROLLBACK ensures data safety. If something fails during the update, all changes will be rolled back.
  2. Update Scenarios:
    • Simple Updates: Modify specific column values.
    • Conditional Updates: Use the WHERE clause to restrict updates.
    • Update with Joins: Update one table's values based on data in another table.
  3. Testing: Always test the UPDATE statements on a staging environment or backup database before applying them in production.
  4. Verification: Run a SELECT statement after updates to verify the changes.

How to Use:

  1. Prepare the XML file with update details.
  2. Run the C# program to generate the migration and rollback scripts.
  3. Execute the generated SQL scripts in SQL Server Management Studio (SSMS) or any SQL client.

To dynamically generate a SQL Server migration script in C# using an XML file as input, you can follow this approach:


Steps Overview:

  1. XML Structure: Define the XML format to store:
    • Table name
    • Columns to update
    • Conditions for the WHERE clause
    • New values for migration
    • Existing values for rollback (downward migration)
  2. C# Application:
    • Parse the XML using XDocument or XmlDocument.
    • Generate dynamic UPDATE statements for both upward (new value) and downward (existing value) migrations.
    • Output the generated SQL scripts to a .sql file or execute them directly.
  3. Execution:
    • Run the generated SQL scripts in your SQL Server environment.

Benefits:

  • Automation: Reduces manual script creation.
  • Rollback Support: Ensures a safe downward migration.
  • Reusability: The XML file can be reused and extended for future migrations.
  • Flexibility: Easily modify or add new updates without changing the C# code.

XML File Example

Here’s an example of how the XML can be structured:

<Migration>

  <Updates>

    <Update>

      <TableName>Employees</TableName>

      <ColumnName>Salary</ColumnName>

      <Variables>

        <Variable>

          <Name>SalesBonus</Name>

          <Value>1000.00</Value>

        </Variable>

        <Variable>

          <Name>ExistingSalary</Name>

          <Value>50000</Value>

        </Variable>

        <Variable>

          <Name>MinExperience</Name>

          <Value>5</Value>

        </Variable>

      </Variables>

      <Conditions>

        <Condition operator="AND">Department = 'Sales'</Condition>

        <Condition operator="AND">Experience > @MinExperience</Condition>

      </Conditions>

      <NewValue>@SalesBonus</NewValue>

      <ExistingValue>@ExistingSalary</ExistingValue>

    </Update>

   

    <Update>

      <TableName>Products</TableName>

      <ColumnName>Price</ColumnName>

      <Variables>

        <Variable>

          <Name>PriceIncreaseFactor</Name>

          <Value>1.10</Value>

        </Variable>

        <Variable>

          <Name>ExistingPrice</Name>

          <Value>Price / 1.10</Value>

        </Variable>

        <Variable>

          <Name>MinStock</Name>

          <Value>100</Value>

        </Variable>

      </Variables>

      <Conditions>

        <Condition operator="OR">Category = 'Electronics'</Condition>

        <Condition operator="OR">Stock < @MinStock</Condition>

      </Conditions>

      <NewValue>@PriceIncreaseFactor * Price</NewValue>

      <ExistingValue>@ExistingPrice</ExistingValue>

    </Update>

  </Updates>

</Migration>

 

Explanation of Changes:

  1. Variables in Conditions:
    • Each update can now have variables defined in the <Variables> section.
    • These variables can be used in the <Conditions> section to dynamically construct the condition expressions.
    • In the Employees example, we use @MinExperience in the condition to check if Experience is greater than the value defined in @MinExperience.
    • In the Products example, we use @MinStock to compare Stock with a dynamic threshold.
  2. Variables in the Conditions Section:
    • The condition now supports the use of variables inside the logical expression.
    • This allows for more dynamic and flexible conditions that depend on variables, making it easier to handle complex scenarios.

Generated T-SQL Migration Script:

Upward Migration (SQL Output):

-- Upward Migration Script

BEGIN TRANSACTION;

 

-- Variables specific to the 'Employees' table update

DECLARE @SalesBonus AS DECIMAL(18, 2) = 1000.00;

DECLARE @ExistingSalary AS DECIMAL(18, 2) = 50000;

DECLARE @MinExperience AS INT = 5;

 

-- Update for Employees

UPDATE Employees

SET Salary = @SalesBonus

WHERE Department = 'Sales' AND Experience > @MinExperience;

 

-- Variables specific to the 'Products' table update

DECLARE @PriceIncreaseFactor AS DECIMAL(18, 2) = 1.10;

DECLARE @ExistingPrice AS DECIMAL(18, 2) = (SELECT Price / 1.10 FROM Products WHERE Category = 'Electronics' OR Stock < 100);

DECLARE @MinStock AS INT = 100;

 

-- Update for Products

UPDATE Products

SET Price = @PriceIncreaseFactor * Price

WHERE Category = 'Electronics' OR Stock < @MinStock;

 

COMMIT TRANSACTION;

 

 

Downward Migration (SQL Output):

-- Downward Migration Script

BEGIN TRANSACTION;

 

-- Variables specific to the 'Employees' table update

DECLARE @SalesBonus AS DECIMAL(18, 2) = 1000.00;

DECLARE @ExistingSalary AS DECIMAL(18, 2) = 50000;

DECLARE @MinExperience AS INT = 5;

 

-- Revert update for Employees

UPDATE Employees

SET Salary = @ExistingSalary

WHERE Department = 'Sales' AND Experience > @MinExperience;

 

-- Variables specific to the 'Products' table update

DECLARE @PriceIncreaseFactor AS DECIMAL(18, 2) = 1.10;

DECLARE @ExistingPrice AS DECIMAL(18, 2) = (SELECT Price / 1.10 FROM Products WHERE Category = 'Electronics' OR Stock < 100);

DECLARE @MinStock AS INT = 100;

 

-- Revert update for Products

UPDATE Products

SET Price = @ExistingPrice

WHERE Category = 'Electronics' OR Stock < @MinStock;

 

COMMIT TRANSACTION;

 

 C# Code for Migration Script Generation (Including Downward Migration):

 

using System;

using System.IO;

using System.Text;

using System.Xml.Linq;


class MigrationScriptGenerator

{

    static void Main()

    {

        string xmlFilePath = "migration.xml";  // Path to your XML file

        XElement migration = XElement.Load(xmlFilePath);


        StringBuilder upwardScript = new StringBuilder();

        StringBuilder downwardScript = new StringBuilder();


        upwardScript.AppendLine("BEGIN TRANSACTION;");

        downwardScript.AppendLine("BEGIN TRANSACTION;");


        foreach (var update in migration.Descendants("Update"))

        {

            string tableName = update.Element("TableName")?.Value;

            string columnName = update.Element("ColumnName")?.Value;

            string newValue = update.Element("NewValue")?.Value;

            string existingValue = update.Element("ExistingValue")?.Value;


            // Get variables

            var variables = update.Element("Variables")?.Elements("Variable");

            foreach (var variable in variables)

            {

                string varName = variable.Element("Name")?.Value;

                string varValue = variable.Element("Value")?.Value;

                upwardScript.AppendLine($"DECLARE @{varName} AS DECIMAL(18, 2) = {varValue};");

                downwardScript.AppendLine($"DECLARE @{varName} AS DECIMAL(18, 2) = {varValue};");

            }


            // Get conditions

            var conditions = update.Element("Conditions")?.Elements("Condition");

            StringBuilder conditionString = new StringBuilder();

            foreach (var condition in conditions)

            {

                if (conditionString.Length > 0)

                    conditionString.Append($" {condition.Attribute("operator")?.Value} ");

                conditionString.Append(condition.Value);

            }


            // Upward Migration Update Script

            upwardScript.AppendLine($"UPDATE {tableName}");

            upwardScript.AppendLine($"SET {columnName} = {newValue}");

            upwardScript.AppendLine($"WHERE {conditionString};");


            // Downward Migration Update Script

            downwardScript.AppendLine($"UPDATE {tableName}");

            downwardScript.AppendLine($"SET {columnName} = {existingValue}");

            downwardScript.AppendLine($"WHERE {conditionString};");

        }


        upwardScript.AppendLine("COMMIT TRANSACTION;");

        downwardScript.AppendLine("COMMIT TRANSACTION;");


        // File paths for upward and downward migration scripts

        string upwardScriptPath = "upward_migration.sql";

        string downwardScriptPath = "downward_migration.sql";


        // Write scripts to files

        File.WriteAllText(upwardScriptPath, upwardScript.ToString());

        File.WriteAllText(downwardScriptPath, downwardScript.ToString());


        Console.WriteLine($"Upward migration script saved to: {upwardScriptPath}");

        Console.WriteLine($"Downward migration script saved to: {downwardScriptPath}");

    }

}

  }

 

 

Explanation of Changes:

  1. Forward Migration:

    • The forward migration updates the specified table and column with the NewValue, based on the conditions defined in the XML.
    • The conditions are joined by their logical operator (AND/OR) to form a complete WHERE clause.
  2. Downward Migration:

    • The downward migration (reverting the changes) updates the table and column with the ExistingValue, using the same conditions for the WHERE clause.
    • The revert operation uses the same conditions and logical operators as the forward migration, ensuring the update is rolled back for the same rows.
  3. Variable Declaration:

    • For each update, any variables (like NewValue, ExistingValue, etc.) are declared before executing the SQL statement, as specified in the XML.
    • Variables are declared as DECIMAL(18, 2), but this can be adjusted if needed.
  4. XML Structure Consideration:

    • The XML structure supports specifying multiple conditions for each update, and logical operators (AND, OR) are used to combine them.
    • Each update in the XML also supports specifying a set of variables to be used in the SQL script.
Generated SQL Script
    

BEGIN TRANSACTION;

 

-- Update for Employees

DECLARE @SalesBonus AS DECIMAL(18, 2) = 1000.00;

DECLARE @ExistingSalary AS DECIMAL(18, 2) = 50000;

DECLARE @MinExperience AS INT = 5;

 

UPDATE Employees

SET Salary = @SalesBonus

WHERE Department = 'Sales' AND Experience > @MinExperience;

 

-- Revert update for Employees

UPDATE Employees

SET Salary = @ExistingSalary

WHERE Department = 'Sales' AND Experience > @MinExperience;

 

-- Update for Products

DECLARE @PriceIncreaseFactor AS DECIMAL(18, 2) = 1.10;

DECLARE @ExistingPrice AS DECIMAL(18, 2) = Price / 1.10;

DECLARE @MinStock AS INT = 100;

 

UPDATE Products

SET Price = @PriceIncreaseFactor * Price

WHERE Category = 'Electronics' OR Stock < @MinStock;

 

-- Revert update for Products

UPDATE Products

SET Price = @ExistingPrice

WHERE Category = 'Electronics' OR Stock < @MinStock;

 

COMMIT TRANSACTION;


How to Use:

  1. Create the XML: Define your XML file with updates, conditions, new values, existing values, and variables.
  2. Update the File Path: Specify the correct file paths in the xmlFilePath and outputFilePath variables.
  3. Run the Program: The program will read the XML, generate the SQL migration script (both forward and backward migrations), and output the SQL to the console or a file.

Editor Config for VB.net and C#

EditorConfig is a configuration file format that standardizes coding styles and conventions across different IDEs and editors. By defining specific rules in a .editorconfig file, teams can ensure consistency in code formatting and maintainability regardless of individual developer environments.

Core Features of EditorConfig

  1. Language-Agnostic Rules: Supports basic formatting rules like indentation, line endings, and trailing whitespace for all file types.
  2. Language-Specific Rules: Supports language-specific conventions, such as .NET coding standards.
  3. IDE Integration: Supported natively or via plugins in most IDEs (e.g., Visual Studio, Rider, VS Code).

Structure of an EditorConfig File

  • root: Marks the top-level .editorconfig file.
  • File Matching: Specifies rules for files using glob patterns (e.g., [*.cs] for C# files).
  • Settings: Key-value pairs to define coding styles.

Common Coding Standards

General Settings
  • indent_style: Defines tabs or spaces (space or tab).
  • indent_size: Sets the number of spaces per indent.
  • end_of_line: Specifies line endings (lf, crlf, or cr).
  • trim_trailing_whitespace: Removes unnecessary spaces at the end of lines.
  • insert_final_newline: Ensures files end with a newline.
Language-Specific Standards
  • C# and .NET Standards:
    • Organizing Usings: Sort using directives and position (inside or outside namespace).
    • Modifier Preferences: Enforce accessibility modifiers and readonly fields.
    • Naming Conventions: Define capitalization and prefix rules for constants, fields, methods, etc.
    • Expression Preferences: Encourage modern patterns like null propagation, collection initializers, and auto-properties.
    Formatting Rules
  • Control spaces, newlines, and indentation for constructs like braces, operators, and control flow statements.

C# & VB.Net Project coding standard editor config:

Add the File to the project and name it as .editorconfig

###############################
# Core EditorConfig Options   #
###############################
root = true
[*]
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
dotnet_style_operator_placement_when_wrapping = beginning_of_line
tab_width = 4
indent_size = 4
end_of_line = crlf
dotnet_style_coalesce_expression = true:suggestion
dotnet_style_null_propagation = true:suggestion
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:silent
dotnet_style_prefer_auto_properties = true:silent
dotnet_style_object_initializer = true:suggestion
dotnet_style_collection_initializer = true:suggestion
dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
dotnet_style_prefer_conditional_expression_over_assignment = true:silent
dotnet_style_prefer_conditional_expression_over_return = true:silent
dotnet_style_explicit_tuple_names = true:suggestion
dotnet_style_prefer_inferred_tuple_names = true:suggestion
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
dotnet_style_prefer_compound_assignment = true:suggestion
dotnet_style_prefer_simplified_interpolation = true:suggestion
dotnet_style_namespace_match_folder = true:suggestion
dotnet_style_readonly_field = true:suggestion
dotnet_style_predefined_type_for_locals_parameters_members = true:silent
dotnet_style_predefined_type_for_member_access = true:silent
dotnet_style_require_accessibility_modifiers = always:error
dotnet_style_allow_multiple_blank_lines_experimental = true:silent
dotnet_style_allow_statement_immediately_after_block_experimental = true:silent
dotnet_code_quality_unused_parameters = all:error
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent
dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent
dotnet_style_qualification_for_field = false:silent
dotnet_style_qualification_for_property = false:silent
dotnet_style_qualification_for_method = false:silent
dotnet_style_qualification_for_event = false:silent

###############################
# C# Naming Conventions       #
###############################
[*.cs]
# Use PascalCase for constant fields
dotnet_naming_symbols.constant_fields.applicable_kinds            = field
dotnet_naming_symbols.constant_fields.applicable_accessibilities  = *
dotnet_naming_symbols.constant_fields.required_modifiers          = const
dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = error
dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols  = constant_fields
dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style

# Name all non-public fields with camelCase
dotnet_naming_symbols.non_public_field_symbol.applicable_kinds = field
dotnet_naming_symbols.non_public_field_symbol.applicable_accessibilities = private,internal,protected,protected_internal
dotnet_naming_style.non_public_field_style.capitalization = camel_case
dotnet_naming_rule.non_public_fields_are_camel_case.symbols = non_public_field_symbol
dotnet_naming_rule.non_public_fields_are_camel_case.style = non_public_field_style

# Name all public fields with PascalCase
dotnet_naming_symbols.public_field_symbol.applicable_kinds = field
dotnet_naming_symbols.public_field_symbol.applicable_accessibilities = public
dotnet_naming_style.public_field_style.capitalization = pascal_case
dotnet_naming_rule.public_fields_are_pascal_case.severity = error
dotnet_naming_rule.public_fields_are_pascal_case.symbols = public_field_symbol
dotnet_naming_rule.public_fields_are_pascal_case.style = pascal_case_style

# All static fields must be PascalCase
dotnet_naming_symbols.static_fields.required_modifiers         = static
dotnet_naming_symbols.static_fields.applicable_kinds           = field
dotnet_naming_rule.static_fields_must_be_pascal_case_rule.symbols    = static_fields
dotnet_naming_rule.static_fields_must_be_pascal_case_rule.style = pascal_case_style
dotnet_naming_rule.static_fields_must_be_pascal_case_rule.severity = error

# Names of parameters must be camelCase
dotnet_naming_symbols.parameter_symbol.applicable_kinds = parameter
dotnet_naming_style.parameter_style.capitalization = camel_case
dotnet_naming_rule.parameters_are_camel_case.severity = error
dotnet_naming_rule.parameters_are_camel_case.symbols = parameter_symbol
dotnet_naming_rule.parameters_are_camel_case.style = parameter_style

# Non-interface types must use PascalCase
dotnet_naming_symbols.non_interface_type_symbol.applicable_kinds = class,struct,enum,delegate
dotnet_naming_style.non_interface_type_style.capitalization = pascal_case
dotnet_naming_rule.non_interface_types_are_pascal_case.severity = error
dotnet_naming_rule.non_interface_types_are_pascal_case.symbols = non_interface_type_symbol
dotnet_naming_rule.non_interface_types_are_pascal_case.style = pascal_case_style

# Interfaces must use PascalCase and start with a prefix of 'I'
dotnet_naming_symbols.interface_type_symbol.applicable_kinds = interface
dotnet_naming_style.interface_type_style.capitalization = pascal_case
dotnet_naming_style.interface_type_style.required_prefix = I
dotnet_naming_rule.interface_types_must_be_prefixed_with_i.severity = error
dotnet_naming_rule.interface_types_must_be_prefixed_with_I.symbols = interface_type_symbol
dotnet_naming_rule.interface_types_must_be_prefixed_with_i.style = interface_type_style

# Methods, Properties, and Events must use PascalCase
dotnet_naming_symbols.member_symbol.applicable_kinds = method,property,event
dotnet_naming_style.member_style.capitalization = pascal_case
dotnet_naming_rule.members_are_pascal_case.severity = error
dotnet_naming_rule.members_are_pascal_case.symbols = member_symbol
dotnet_naming_rule.members_are_pascal_case.style = pascal_case_style

###############################
# VB.NET Naming Conventions   #
###############################
[*.vb]
# Use PascalCase for constant fields
dotnet_naming_symbols.constant_fields.applicable_kinds            = field
dotnet_naming_symbols.constant_fields.applicable_accessibilities  = *
dotnet_naming_symbols.constant_fields.required_modifiers          = const
dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = error
dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols  = constant_fields
dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style

# Name all non-public fields with camelCase
dotnet_naming_symbols.non_public_field_symbol.applicable_kinds = field
dotnet_naming_symbols.non_public_field_symbol.applicable_accessibilities = private,internal,protected,protected_internal
dotnet_naming_style.non_public_field_style.capitalization = camel_case
dotnet_naming_rule.non_public_fields_are_camel_case.symbols = non_public_field_symbol
dotnet_naming_rule.non_public_fields_are_camel_case.style = non_public_field_style

# Name all public fields with PascalCase
dotnet_naming_symbols.public_field_symbol.applicable_kinds = field
dotnet_naming_symbols.public_field_symbol.applicable_accessibilities = public
dotnet_naming_style.public_field_style.capitalization = pascal_case
dotnet_naming_rule.public_fields_are_pascal_case.severity = error
dotnet_naming_rule.public_fields_are_pascal_case.symbols = public_field_symbol
dotnet_naming_rule.public_fields_are_pascal_case.style = pascal_case_style

# All static fields must be PascalCase
dotnet_naming_symbols.static_fields.required_modifiers         = static
dotnet_naming_symbols.static_fields.applicable_kinds           = field
dotnet_naming_rule.static_fields_must_be_pascal_case_rule.symbols    = static_fields
dotnet_naming_rule.static_fields_must_be_pascal_case_rule.style = pascal_case_style
dotnet_naming_rule.static_fields_must_be_pascal_case_rule.severity = error

# Names of parameters must be camelCase
dotnet_naming_symbols.parameter_symbol.applicable_kinds = parameter
dotnet_naming_style.parameter_style.capitalization = camel_case
dotnet_naming_rule.parameters_are_camel_case.severity = error
dotnet_naming_rule.parameters_are_camel_case.symbols = parameter_symbol
dotnet_naming_rule.parameters_are_camel_case.style = parameter_style

# Non-interface types must use PascalCase
dotnet_naming_symbols.non_interface_type_symbol.applicable_kinds = class,struct,enum,delegate
dotnet_naming_style.non_interface_type_style.capitalization = pascal_case
dotnet_naming_rule.non_interface_types_are_pascal_case.severity = error
dotnet_naming_rule.non_interface_types_are_pascal_case.symbols = non_interface_type_symbol
dotnet_naming_rule.non_interface_types_are_pascal_case.style = pascal_case_style

# Interfaces must use PascalCase and start with a prefix of 'I'
dotnet_naming_symbols.interface_type_symbol.applicable_kinds = interface
dotnet_naming_style.interface_type_style.capitalization = pascal_case
dotnet_naming_style.interface_type_style.required_prefix = I
dotnet_naming_rule.interface_types_must_be_prefixed_with_i.severity = error
dotnet_naming_rule.interface_types_must_be_prefixed_with_I.symbols = interface_type_symbol
dotnet_naming_rule.interface_types_must_be_prefixed_with_i.style = interface_type_style

# Methods, Properties, and Events must use PascalCase
dotnet_naming_symbols.member_symbol.applicable_kinds = method,property,event
dotnet_naming_style.member_style.capitalization = pascal_case
dotnet_naming_rule.members_are_pascal_case.severity = error
dotnet_naming_rule.members_are_pascal_case.symbols = member_symbol
dotnet_naming_rule.members_are_pascal_case.style = pascal_case_style


###############################
# Naming Conventions (Unified) #
###############################

# Both C# and VB.NET rules
[*.{cs,vb}]
# Method names should be in PascalCase
dotnet_naming_rule.methods_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.methods_should_be_pascal_case.symbols = methods
dotnet_naming_rule.methods_should_be_pascal_case.style = pascal_case

# Local variables should be in camelCase
dotnet_naming_rule.local_variables_should_be_camel_case.severity = suggestion
dotnet_naming_rule.local_variables_should_be_camel_case.symbols = local_variables
dotnet_naming_rule.local_variables_should_be_camel_case.style = camel_case


Featured Posts

How to generate Database Migration script dynamically by using XML

 Generating migration scripts dynamically using XML offers several advantages, particularly in software development and database management....

Popular Posts