Resolving the SqlBulkTools Issue: Exposing Private Fields for Clean Serialization and Deserialization.

Understanding the Issue with SqlBulkTools

As a technical blogger, I’ve encountered numerous issues when working with different libraries and frameworks. Recently, I came across an issue with the C# package SqlBulkTools that was causing problems for one of my developers. The problem was related to how the package handles serialization and deserialization of data from XML files.

Background Information

The developer was using a base class called ChathamBase and another class, let’s call it OwnershipPeriod, which inherited from ChathamBase. The OwnershipPeriod class had properties with nullable datatypes. When trying to bulk insert these objects into the database using SqlBulkTools, only the first column (from the base class) was being inserted/updated.

The Problem

The problem lay in how SqlBulkTools handles serialization and deserialization of data from XML files. As it turns out, the package only loops through the type’s properties, ignoring any other fields. This is a common design pattern used in many libraries to ensure that only publicly exposed properties are serialized.

The Solution

To solve this issue, we need to rethink our approach to exposing private fields instead of using them directly. We can achieve this by creating public methods or properties that wrap around the private fields.

Exposing Private Fields

In the OwnershipPeriod class, we can add a public property for each field, like so:

public int TransactionIdentifier { get; set; }

public decimal OwnershipPercentage { get; set; }

public DateTime OwnershipPercentageEffectiveDate { get; set; }

public string OwnershipStructure { get; set; }

However, since the fields are nullable, we need to use the nullable keyword:

public Nullable<decimal> OwnershipPercentage { get; set; }

public Nullable<DateTime> OwnershipPercentageEffectiveDate { get; set; }

public Nullable<string> OwnershipStructure { get; set; }

By doing this, we’re effectively exposing these fields as public properties that can be accessed directly.

Updating the BulkInsertOrUpdate Method

Now that we have exposed the private fields as public properties, we need to update the BulkUpsert method to use these properties instead of the fields directly.

internal static void BulkUpsert(string connectionName, IEnumerable<OwnershipPeriod> op)
{
    BulkOperations bulk = new BulkOperations();

    using (TransactionScope trans = new TransactionScope())
    {
        using (SqlConnection cn = GetConnection(connectionName))
        {
            bulk.Setup<OwnershipPeriod>()
                .ForCollection(op)
                .WithTable("OwnershipPeriod")
                .AddAllColumns()
                .BulkInsertOrUpdate()
                // .SetIdentityColumn(x => x.TransactionIdentifier)
                .MatchTargetOn(x => x.TransactionIdentifier)
                .Commit(cn);
        }

        trans.Complete();
    }
}

Conclusion

By following these steps, we’ve successfully resolved the issue with SqlBulkTools and our custom class OwnershipPeriod. By exposing private fields as public properties, we can ensure that all fields are included in the serialization and deserialization process. This approach is commonly used in many libraries to maintain a clean and consistent coding standard.

Reference


Last modified on 2025-02-01