1

複数の列に対する単純な SQL LEFT OUTER JOIN と where 句を動作中の Linq-to-Entities クエリに変換する方法を理解するのに非常に苦労しています。テーブルは2つしかありません。Table2 の一致に関係なく、Table1 のすべての行の値が必要ですが、複数の列を結合することは困難です。また、クエリで簡単な計算を行う必要がありますが、それも見つかりません。SQL でのクエリは次のようになります。

select t1.tableid1,
t1.tableid2,
t1.fieldvalue1,
t2.fieldvalue2,
isnull(t2.fieldvalue2,0) / t1.fieldvalue1 as calcvalue
t1.fieldvalue1 - isnull(t2.fieldvalue2,0) as calcvalue2
from table1 t1
left outer join table2 t2 
    on t1.tableid1 = t2.tableid1
    and t1.tableid2 = t2.tableid2
    and t1.tableid3 = t2.tableid3
where t1.tableid1 = @somevalue

単一の列の左結合を実行できますが、列の値を加算または減算する方法がわからないことは言うまでもなく、複数の列の適切な構文を見つけることができないようです。以下は私の最善の推測ですが、次の場合に Type Expected エラーが発生します (「new」の後、最初の開き括弧の前):

On New (t2.Field(Of String)("tableid1"), t2.Field(Of String)

最良の推測:

Dim query = From t1 In dtTable1 _
                         Group Join t2 In dtTable2 _
                         On New (t2.Field(Of String)("tableid1"), t2.Field(Of String)("tableid2")) Equals _
                            (t1.Field(Of String)("tableid1"), t1.Field(Of String)("tableid2")) _
                         Into t2outer = Group _
                         From t2 In t2outer.DefaultIfEmpty() _
                         Select New With _
                        { _
                            .t1_tableid1 = t1.Field(Of String)("tableid1"), _
                            .t1_tableid2 = t1.Field(Of String)("tableid2"), _
                            .t1_fieldvalue1 = t1.Field(Of Integer)("fieldvalue1"))
                            .t2_fieldvalue2 = If(t2 Is Nothing, CType("0", Integer), t2.Field(Of Integer)("fieldvalue2"))
                        }

@Gertそれで十分に近づきました。括弧ではなく中括弧を追加する必要があり、「キー」キーワードとIDの間にスペースを配置したため、フォーマットが少しずれていたと思います。

On New With {
                        Key .id1 = t2.Field(Of String)("tableid1"), _
                        Key .id2 = t2.Field(Of String)("tableid2")
                        } _
                    Equals _
                    New With {
                        Key .id1 = t1.Field(Of String)("tableid1"), _
                        Key .id2 = t1.Field(Of String)("tableid2")
                        } _

Gert のおかげで、SQL クエリで説明されているようにこれを機能させることができました。SQL クエリの完全に機能する表現については、以下を参照してください。

Dim query = From t1 In dtTable1 _
    Where (T1.Field(Of String)("fieldvalue1") = SOMEVALUE) _
     Group Join t2 In dtTable2 _
     On New (t2.Field(Of String)("tableid1"), t2.Field(Of String)("tableid2")) Equals _
        (t1.Field(Of String)("tableid1"), t1.Field(Of String)("tableid2")) _
     Into t2outer = Group _
     From t2 In t2outer.DefaultIfEmpty() _
     Select New With _
    { _
        .t1_tableid1 = t1.Field(Of String)("tableid1"), _
        .t1_tableid2 = t1.Field(Of String)("tableid2"), _
        .t1_fieldvalue1 = t1.Field(Of Integer)("fieldvalue1"))
        .t2_fieldvalue2 = If(t2 Is Nothing, CType("0", Integer), t2.Field(Of Integer)("fieldvalue2"))
        .calcvalue = If(t2.Field(Of Integer)("fieldvalue2") Is Nothing, CType("0", Integer), t2.Field(Of Integer)("fieldvalue2")) _
            / CType(t1.Field(Of String)("fieldvalue1"), Integer), 
        .calcvalue2 = CType(t1.Field(Of String)("fieldvalue1"), Integer) _
            - If(t2.Field(Of Integer)("fieldvalue2") Is Nothing, CType("0", Integer), t2.Field(Of Integer)("fieldvalue2")) _
    }
4

2 に答える 2

0

まず、複数のフィールドでグループ化すると、匿名型を比較しているため、その部分

On
   New (t2.Field(Of String)("tableid1"), t2.Field(Of String)("tableid2"))
Equals
       (t1.Field(Of String)("tableid1"), t1.Field(Of String)("tableid2"))

匿名型を作成するための構文に変更する必要があります (後でクエリで使用するものと同じです)。

On
  New With {.id1 = t2.Field(Of String)("tableid1"),
            .id2 = t2.Field(Of String)("tableid2")}
Equals
  New With {.id1 = t1.Field(Of String)("tableid1"),
            .id2 = t1.Field(Of String)("tableid2")}

しかし

C# ではこれで十分です。匿名型では、C# コンパイラはに基づく等価性を使用するためです。ただし、何らかの理由で、VB ではこれが異なり、参照の等価性を使用します。最初のオブジェクトは 2 番目のオブジェクトと同じではないため、はEquals常にです。false

さいわい、VB には、Key無名オブジェクトを比較するときに使用するプロパティを指定できるキーワードがあります。したがって、最終的な構文は次のとおりです。

On
  New With {Key .id1 = t2.Field(Of String)("tableid1"),
            Key. id2 = t2.Field(Of String)("tableid2")}
Equals
  New With {Key .id1 = t1.Field(Of String)("tableid1"),
            Key .id2 = t1.Field(Of String)("tableid2")}
于 2013-06-23T09:44:17.553 に答える
0

エンティティを使用すると、コンテナーがあり、名前でテーブルを評価します。この where 句は、フィールド値によって結果をフィルタリングし、さらに多くの値と連結できます。{} 内の部分は、エンティティに合わせて変更するためのものです。このクエリはIEnumerable(Of {your entity})- データバインディングに最適です。

Dim query = model.{table name}.Where(Function(o) o.{column name} = {some value}).ToList()
于 2013-06-23T02:10:08.543 に答える