複数のDBMSから取得したDataTable比較 への返答

投稿で使用できる特殊コードの説明。(別タブで開きます。)
本名は入力しないようにしましょう。
投稿した後で削除するときに使うパスワードです。返答があった後は削除できません。
返答する人が目安にします。相手が小学生か社会人かで返答の仕方も変わります。
最初の投稿が質問の場合、質問者が解決時にチェックしてください。(以降も追加書き込み・返信は可能です。)
※「過去ログ」について書くときはその過去ログのURLも書いてください。

以下の返答は逆順(新しい順)に並んでいます。

投稿者 YUU  (社会人) 投稿日時 2015/12/9 13:52:58
返信ありがとうございました。

.?演算子知りませんでした。 勉強不足ですね、

ありがとうございます。無事実行できました。
投稿者 YuO  (社会人) 投稿日時 2015/12/8 23:43:43
.NET Frameworkのバージョンには関係しません。
ただし,.?演算子はVB14の追加機能なので,それより前のVBのコンパイラを使う場合は,コードをそれに対応させる必要があります。
幸い,?.演算子は
・オブジェクトがNothingでなければそのメンバーへのアクセスを行う
・オブジェクトがNothingであればメンバーへのアクセスを行わず,式の値はNothingになる
という演算子なので,ほぼ機械的にIf演算子に置き換えることができます。
# 値型に関して,元のメンバーアクセスの結果がT型ならばT?型になります。

If(succ.X?.Equals(succ.Y), False)
を直接置き換えるなら,
If(If(succ.X IsNot Nothing, succ.X.Equals(succ.Y), DirectCast(Nothing, Boolean?)), False)
でしょうか。
今回は内側のIf演算子がBoolean?型で,Nothingを返すのは条件がFalseの時のみであるため,二つのIf演算子をまとめて
If(succ.X IsNot Nothing, succ.X.Equals(succ.Y), False)
とした方が賢いですが。

ref)
What's New for Visual Basic : https://msdn.microsoft.com/ja-jp/library/we86c8x2(v=vs.140).aspx
Null 条件演算子 (C# および Visual Basic) : https://msdn.microsoft.com/ja-jp/library/dn986595(v=vs.140).aspx
投稿者 YUU  (社会人) 投稿日時 2015/12/8 20:06:23
返信ありがとうございます。

変更後、確認をしたのですがやはりエラーが出てしまうみたいです。

If(succ.X?.Equals(succ.Y), False)部分にて二つのエラーが出ております。

○If演算子には2つまたは3つのオペランドが必要です。
○?文字はここでは使用できません。

上記のエラー内容です。ちなみにFrameWorksは4.0です。
投稿者 YuO  (社会人) 投稿日時 2015/12/8 18:35:11
.net文法というのがVisual Basicのことであるとして,
if (DBNull.Value.Equals(succ.X) || DBNull.Value.Equals(succ.Y)) return acc && (succ.X?.Equals(succ.Y) ?? false);

は,単純に||演算子をOrElseに,&&演算子をAndAlsoに,??演算子をIf式に置き換えて,
If DBNull.Value.Equals(succ.X) OrElse DBNull.Value.Equals(succ.Y) Then Return acc AndAlso If(succ.X?.Equals(succ.Y), False)
かと。
# 最近はDapper経由でオブジェクトに詰めてしまうことが多いなぁ……。
投稿者 YUU  (社会人) 投稿日時 2015/12/8 18:07:49

現在OracleとSqlserverから取得したDataTableを比較するプログラムを作成しております。

Oracleデータ ⇒ DataTable1
Sqlserverデータ ⇒ DataTable2

このご時世Entity Frameworkをなぜ使わぬといった話ですが今回はDataTableにて比較を行いたいと考えております。

http://qa.atmarkit.co.jp/q/9488

上記サイトを参考にLinq ラムダ式にて一つ一つループで回して比較するすべから逃れられそうなのですが如何せんC#の文法に苦戦しております。

現在最後に回答されている方の方式を.netの文法に置き換えているのですが置き換え方が分からない文法が有ります。(1人目の方はできました。)


Class DataRowComparer
    Implements IEqualityComparer(Of DataRow)

    Public Overloads Function Equals(x As DataRow, y As DataRow) As Boolean Implements IEqualityComparer(Of System.Data.DataRow).Equals
        Return Object.ReferenceEquals(x, y) OrElse (x IsNot Nothing AndAlso y IsNot Nothing AndAlso CompareAllColumns(x, y))
    End Function

    Private Function CompareAllColumns(x As DataRow, y As DataRow) As Boolean

        Dim intColumns As String() = New String() {"ID"}

        Return New String() {"ID", "Name"}.Select(Function(name) New With {.Name = name,
                                                                           .X = x(name),
                                                                           .Y = y(name),
                                                                           .IsInt = intColumns.Contains(name)}).Aggregate(True, Function(acc, succ)
                                                                                                                                    '下記のコメントアウト部分です。
                                                                                                                                    'if (DBNull.Value.Equals(succ.X) || DBNull.Value.Equals(succ.Y)) return acc && (succ.X?.Equals(succ.Y) ?? false);
                                                                                                                                    
    If succ.IsInt Then
                                                                                                                                        Return acc AndAlso (CInt(succ.X) = CInt(succ.Y))
                                                                                                                                    End If

                                                                                                                                    Return acc AndAlso (succ.X Is succ.Y)

                                                                                                                                End Function)

    End Function

    Public Overloads Function GetHashCode(obj As DataRow) As Integer Implements IEqualityComparer(Of System.Data.DataRow).GetHashCode

        If obj Is Nothing Then
            Return 0
        End If

        Dim idHashCode As Integer = If(obj("ID") Is Nothing, 0, obj("ID").GetHashCode())
        Dim nameHashCode As Integer = If(obj("Name") Is Nothing, 0, obj("Name").GetHashCode())

        Return idHashCode Xor nameHashCode

    End Function

End Class

上記のコメントアウト部分以外は.net文法に直せたかと思うのですがコメントの部分のみうまく変換できません。(それら以外は多分できたのかな?)

お力を貸していただけると幸いです。