1

私は2つのテーブルを持っています

表 A:

TableAID int,
Col1 varchar(8)

表 B:

TableBID int
Col1 char(8),
Col2 varchar(40)

2 つのテーブルで SQL クエリを実行すると、次の行数が返されます

SELECT * FROM tableA (7200 rows)
select * FROM tableB (28030 rows)

col1 で結合してデータを選択すると、次の行数が返されます

select DISTINCT a.Col1,b.Col2 FROM tableA a
join tableB b on a.Col1=b.Col1 (6578 rows)

上記の 2 つのテーブルは異なるデータベースにあるため、2 つの EF モデルを作成し、データを個別に再試行し、次の関数で linq を使用してコードに結合しようとしました。驚くべきことに、6578 レコードではなく 2886 レコードが返されます。私は何か間違ったことをしていますか?個々のリストは正しいデータを返すようですが、SQL クエリと linq クエリを結合すると、レコード数が異なります。

これに関するヘルプは大歓迎です。

// This function is returning 2886 records      
public List<tableC_POCO_Object> Get_TableC() 
{
    IEnumerable<tableC_POCO_Object> result = null;
    List<TableA> tableA_POCO_Object = Get_TableA(); // Returns 7200 records
    List<TableB> tableB_POCO_Object = Get_TableB(); // Returns 28030 records
    result = from tbla in tableA_POCO_Object
         join tblb in tableB_POCO_Object on tbla.Col1 equals tblb.Col1
         select new tableC_POCO_Object 
         {
         Col1 = tblb.Col1,
         Col2 = tbla.Col2
         };
    return result.Distinct().ToList();
}
4

3 に答える 3

2

問題は、POCO の世界では、2 つの文字列を直接比較 (大文字と小文字が区別される) を使用して比較しようとしているという事実にあります。これは SQL の世界では機能するかもしれませんが (もちろん、大文字と小文字の区別を有効にしていない限り) "stringA" == "StringA"、. すべきことは、結合列をすべて大文字または小文字に正規化することです。

join tblb in tableB_POCO_Object on tbla.Col1.ToUpper() equals tblb.Col1.ToUpper()

結合演算子は、指定されたキー (2 番目のコレクションから開始) を使用してルックアップを作成し、生成されたルックアップをチェックして元のテーブル/コレクションを結合し直すため、ハッシュが異なる場合は結合されません。

ポイントは、同じ cAsE に正規化しない限り、文字列データ/プロパティで OBJECT コレクションを結合することは悪いことです。一部の DB プロバイダーへの LINQ では、データベースで大文字と小文字が区別されない場合、これは問題になりませんが、CLR/L2O の世界では常に問題になります。

編集:ああ、それがCHAR(8)の代わりであることに気づきませんでしVARCHAR(8)た。つまり、何があっても8文字にパディングされます。その場合、tblb.Col1.Trim()問題を修正します。ただし、LINQ to Objects クエリを扱うときは、この点に留意してください。

于 2012-05-29T19:29:44.153 に答える
0

VARCHARこれは、と列を比較したために発生する可能性がありCHARます。SQL では、これは SQL サーバーの設定に依存しますがANSI_PADDING、C# では、文字列値は DataReader を使用して読み取られ、標準の文字列関数を使用して比較されます。

tblb.Col1.Trim()LINQ ステートメントで試してください。

于 2012-05-29T19:35:31.147 に答える
0

SPFiredrakeが正しく指摘したように、これは大文字と小文字の区別が原因である可能性がありますが、なぜそのような方法でコードを書いたのか、なぜこの方法ではないのかを尋ねなければなりません:

// This function is returning 2886 records      
public List<tableC_POCO_Object> Get_TableC() 
{
    return from tbla in Get_TableA()
           join tblb in Get_TableB() on tbla.Col1 equals tblb.Col1
           select new tableC_POCO_Object 
           {
             Col1 = tblb.Col1,
             Col2 = tbla.Col2
           }.Distinct().ToList();
}

ここで、Get_TableA() と Get_TableB() は List ではなく IEnumerable を返します。リストに変換するとクエリが即座に実行されるため、これに注意する必要があります。単一のクエリをデータベース サーバーに送信したいと考えています。

于 2012-05-29T20:23:02.060 に答える