Tim Schmelter
Tim Schmelter

Reputation: 460038

LINQ: Except doesn't work in the expected way

I've problems to detect if there are new rows in a DataTable Email_Total that is yet not imported into ContactDetail.

Dim srcUnique = From row In src.Email_Total
                Select row.ticket_id, row.interaction, row.modified_time
Dim destUnique = From row In dest.ContactDetail
                Where row.ContactRow.ContactTypeRow.idContactType = emailContactTypeID
               Select row.ContactRow.Ticket_ID, row.Interaction, row.ModifiedAt
Dim diff = srcUnique.Except(destUnique)
Dim needUpdate = diff.Any

I have to compare the data on multiple columns because the ID is not equal in both tables.

This works until i've added row.modified_time/row.ModifiedAt columns(both DateTime) to the select, because rows are only unique if all three values are equal. If i add the the date-column as third argument the compiler shows following error(on srcUnique.Except(destUnique)):

'System.Data.EnumerableRowCollection(Of <anonymous type>)' cannot be converted to 'System.Collections.Generic.IEnumerable(Of <anonymous type>)' because '<anonymous type> (line 471)' is not derived from '<anonymous type> (line 468)', as required for the 'Out' generic parameter 'T' in 'Interface IEnumerable(Of Out T)'

The strange thing is that the error is also shown when i remove the row.Interaction-column from the selects and leave only the Ticket_ID and Modified_Time but it works if i use the Ticket_ID and Interaction columns.

Note: src and dest are strong typed DataSets and the schema of both DataTables is slightly different, but i think that this issue is not only related to LINQ-to-DataSet.

Edit: these are the datamodels(Ticket_ID int,Interaction int, ModifiedAt DateTime)

enter image description here enter image description here

Solution: (thanks to @Stuart)

Dim srcUnique = From row In src.Email_Total
          Select Ticket_ID = row.ticket_id, Interaction = row.interaction, ModifiedAt = row.modified_time
Dim destUnique = From row In dest.ContactDetail
                Where row.ContactRow.ContactTypeRow.idContactType = emailContactTypeID
          Select row.ContactRow.Ticket_ID, row.Interaction, row.ModifiedAt

Upvotes: 0

Views: 1258

Answers (2)

Stuart
Stuart

Reputation: 66882

I don't speak VB... but in C# you'd need to make the spelling (including capitalization) and Types of all the property names are the same in order to get this to work:

i.e. this would fail

var srcUnique = from row in src.Email_Total
            select new { row.ticket_id, row.interaction, row.modified_time };
var destUnique = from row in dest.ContactDetail
            where row.ContactRow.ContactTypeRow.idContactType == emailContactTypeID
            select new { row.ContactRow.Ticket_ID, row.Interaction, row.ModifiedAt };
var diff = srcUnique.Except(destUnique);

but this would succeed:

var srcUnique = from row in src.Email_Total
            select new { Ticket_ID = row.ticket_id, Interaction = row.interaction, ModifiedAt = row.modified_time };
var destUnique = from row in dest.ContactDetail
            where row.ContactRow.ContactTypeRow.idContactType == emailContactTypeID
            select new { row.ContactRow.Ticket_ID, row.Interaction, row.ModifiedAt };
var diff = srcUnique.Except(destUnique);

(Assuming that the Types are the same)

Upvotes: 3

Manu
Manu

Reputation: 29143

In the select list, the names, order and types of the variables must be the same.

Upvotes: 1

Related Questions