Skip to content

Bug: BulkMergeAsync with multiple qualifiers #864

@nandaccio

Description

@nandaccio

It seems that BulkMergeAsync does not work as expected in case of multiple qualifiers. See further details below.

At every run the same records are added, even though they are already available (based on the qualifiers):

First run:
1 (2)

Second run:
2 (2)

Third run:
3

I am using the following call to populate the table:

merged = await database.Do.BulkMergeAsync(transactions.ToList(), qualifiers: p => new { p.TransactionID, p.TransactionDate, p.AccountId, p.TransactionTypeID, p.Attribute1, p.Attribute2, p.Attribute3, p.Attribute4 }, hints: SqlServerTableHints.TabLock, bulkCopyTimeout: 0).ConfigureAwait(false);

where transactions is a List (coming from HashSet with a custom comparer, see below):

public class TransactionRaw
    {
        public long Id { get; set; }

        public long TransactionID { get; set; }

        public DateTime TransactionDate { get; set; }

        public DateTime IncidentCreationDate { get; set; }

        public int? AccountId { get; set; }

        public long? ContactID { get; set; }

        public int? SeverityID { get; set; }

        public int? InterfaceID { get; set; }

        public int? DispositionID { get; set; }

        public long? Attribute1 { get; set; }

        public long? Attribute2 { get; set; }

        public long? Attribute3 { get; set; }

        public long? Attribute4 { get; set; }

        public int? QueueID { get; set; }

        public int? TransactionTypeID { get; set; }

        public int? SourceLevel1ID { get; set; }

        public int? SourceLevel2ID { get; set; }

        public int? ProductID { get; set; }

        public int? CountryID { get; set; }

        public int? CustomerTypeID { get; set; }

        public int? CategoryID { get; set; }

        public int? StatusID { get; set; }

        public string PhoneCallUUID { get; set; }

        public int? ChannelID { get; set; }
    }

In order to avoid duplicates, the hashset uses this custom comparer:

    public class TransactionComparer : IEqualityComparer<TransactionRaw>
    {
        public bool Equals(TransactionRaw t1, TransactionRaw t2)
        {
            return (t1.TransactionID == t2.TransactionID) && (t1.TransactionDate == t2.TransactionDate) && (t1.Attribute1 == t2.Attribute1) && (t1.Attribute2 == t2.Attribute2) && (t1.Attribute3 == t2.Attribute3) && (t1.Attribute4 == t2.Attribute4) && (t1.AccountId == t2.AccountId);
        }

        public int GetHashCode(TransactionRaw t)
        {
            return $"{t.TransactionID}{t.TransactionDate}{t.AccountId}{t.Attribute1}{t.Attribute2}{t.Attribute3}{t.Attribute4}".GetHashCode();
        }
    }

the schema contains the following table:

CREATE TABLE [TransactionsRaw](
	[Id] [bigint] IDENTITY(1,1) NOT NULL,
	[TransactionID] [bigint] NOT NULL,
	[TransactionDate] [datetime] NOT NULL,
	[AccountId] [int] NULL,
	[ProductID] [int] NULL,
	[Attribute1] [bigint] NULL,
	[Attribute2] [bigint] NULL,
	[Attribute3] [bigint] NULL,
	[Attribute4] [bigint] NULL,
	[PhoneCallUUID] [varchar](64) NULL,
	[InterfaceID] [int] NULL,
	[CategoryID] [int] NULL,
	[ContactID] [int] NULL,
	[CountryID] [int] NULL,
	[CustomerTypeID] [int] NULL,
	[QueueID] [int] NULL,
	[IncidentCreationDate] [datetime] NOT NULL,
	[StatusID] [int] NULL,
	[SeverityID] [int] NULL,
	[SourceLevel1ID] [int] NULL,
	[SourceLevel2ID] [int] NULL,
	[DispositionID] [int] NULL,
	[TransactionTypeID] [int] NULL,
	[ChannelID] [int] NULL
) ON [PRIMARY]

Library Version:

RepoDb.1.12.7
RepoDb.MySql.1.1.4
RepoDb.SqlServer.1.1.3
RepoDb.SqlServer.BulkOperations.1.1.4

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingdeployedFeature or bug is deployed at the current releasefixedThe bug, issue, incident has been fixed.priorityTop priority feature or things to do

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions