質問編集履歴
3
タグを追加 \(LINQ to Entities, Entity Framework\)
title
CHANGED
File without changes
|
body
CHANGED
File without changes
|
2
StackOverflowで見つけた内容
title
CHANGED
File without changes
|
body
CHANGED
@@ -211,6 +211,23 @@
|
|
211
211
|
LEFT OUTER JOIN [dbo].[AAA] AS [Extent2] ON 1 = 0
|
212
212
|
```
|
213
213
|
|
214
|
+
### 追記:StackOverflowで見つけた内容
|
215
|
+
|
216
|
+
http://stackoverflow.com/questions/10642421/using-equal-and-not-equal-in-a-linq-join
|
217
|
+
|
218
|
+
> A join clause performs an equijoin. In other words, you can only base matches on the equality of two keys.
|
219
|
+
> Other types of comparisons such as "greater than" or "not equals" are not supported.
|
220
|
+
|
221
|
+
|
222
|
+
> join節が等価結合を実行します。 言い換えれば、2つのキーが等しいかどうかに基づいて照合を行うことができます。
|
223
|
+
> 「より大きい」または「等しくない」などの他のタイプの比較はサポートされていません。
|
224
|
+
|
225
|
+
上記の質問内容は `LEFT JOIN AAA ON (AAA.RoleName <> 'Admin')` みたいなのはできないの?という内容で 私の問題とは少し違うのですが… 系統的には似てるかなと。
|
226
|
+
|
227
|
+
結局 単純な等価評価しかサポートしていないということでしょうか。
|
228
|
+
|
229
|
+
# EntityFramework を使う人は適用期間を見たりするSQLとかって組まないのでしょうか…?
|
230
|
+
|
214
231
|
###一応考えた方法
|
215
232
|
|
216
233
|
Where 句で見る…? というのを一応考えたのですが、他に方法がないものかと思い質問させて頂きました。
|
1
IEquatableを実装してみました
title
CHANGED
File without changes
|
body
CHANGED
@@ -123,6 +123,94 @@
|
|
123
123
|
なんとなく駄目なパターンはわかったのですが、どうすれば目的の条件で抽出できるのかわかりません。
|
124
124
|
|
125
125
|
|
126
|
+
###追記:IEquatable を実装してみた版(うまくいかず)
|
127
|
+
|
128
|
+
```VBnet
|
129
|
+
Public Class JoinParamMainAndAAA : Implements IEquatable(Of Object)
|
130
|
+
Public Property ID As String = Nothing
|
131
|
+
Public Property StartYmd As String = Nothing
|
132
|
+
Public Property EndYmd As String = Nothing
|
133
|
+
Public Property Ymd As String = Nothing
|
134
|
+
Public Enum TableTypes
|
135
|
+
Main
|
136
|
+
AAA
|
137
|
+
End Enum
|
138
|
+
Public Property TableType As TableTypes
|
139
|
+
|
140
|
+
Public Overloads Function Equals(ByVal obj As Object) As Boolean Implements IEquatable(Of Object).Equals
|
141
|
+
' 想定している型でなければ抜ける
|
142
|
+
If obj Is Nothing OrElse obj.GetType() IsNot GetType(JoinParamMainAndAAA) Then
|
143
|
+
Return False
|
144
|
+
End If
|
145
|
+
Dim chk = CType(obj, JoinParamMainAndAAA)
|
146
|
+
|
147
|
+
Dim m As JoinParamMainAndAAA = Nothing
|
148
|
+
Dim a As JoinParamMainAndAAA = Nothing
|
149
|
+
Select Case(Me.TableType)
|
150
|
+
Case TableTypes.Main:
|
151
|
+
' 自分がMainの場合は相手はAAA
|
152
|
+
If chk.TableType = TableTypes.AAA Then
|
153
|
+
m = Me
|
154
|
+
a = chk
|
155
|
+
End If
|
156
|
+
Case TableTypes.AAA:
|
157
|
+
' 自分がAAAの場合は相手はMain
|
158
|
+
If chk.TableType = TableTypes.Main Then
|
159
|
+
m = chk
|
160
|
+
a = Me
|
161
|
+
End If
|
162
|
+
End Select
|
163
|
+
If m Is Nothing OrElse a Is Nothing Then Return False
|
164
|
+
|
165
|
+
' 比較
|
166
|
+
If m.ID = a.ID AndAlso
|
167
|
+
a.StartYmd <= m.Ymd AndAlso m.Ymd <= a.EndYmd Then
|
168
|
+
Return True
|
169
|
+
End If
|
170
|
+
|
171
|
+
Return False
|
172
|
+
End Function
|
173
|
+
|
174
|
+
Public Overrides Function GetHashCode() As Integer
|
175
|
+
Return CType(Me.ID.GetHashCode() ^ Me.Ymd.GetHashCode() ^ Me.StartYmd.GetHashCode() ^ Me.EndYmd.GetHashCode(), Integer)
|
176
|
+
End Function
|
177
|
+
End Class
|
178
|
+
```
|
179
|
+
|
180
|
+
```VBnet
|
181
|
+
...
|
182
|
+
Group Join a In dbContext.AAA On New JoinParamMainAndAAA With {
|
183
|
+
.TableType = JoinParamMainAndAAA.TableTypes.Main,
|
184
|
+
.ID = m.ID,
|
185
|
+
.Ymd = m.Ymd,
|
186
|
+
.StartYmd = Nothing,
|
187
|
+
.EndYmd = Nothing
|
188
|
+
} Equals New JoinParamMainAndAAA With {
|
189
|
+
.TableType = JoinParamMainAndAAA.TableTypes.AAA,
|
190
|
+
.ID = a.ID,
|
191
|
+
.Ymd = Nothing,
|
192
|
+
.StartYmd = a.StartYmd,
|
193
|
+
.EndYmd = a.EndYmd
|
194
|
+
}
|
195
|
+
...
|
196
|
+
|
197
|
+
' 不要な値にもNothingをセットしているのは、そうしないと以下のエラーが出た為
|
198
|
+
' The type 'TestTest.JoinParamMainAndAAA' appears in two structurally incompatible initializations within a single LINQ to Entities query. A type can be initialized in two places in the same query, but only if the same properties are set in both places and those properties are set in the same order.
|
199
|
+
```
|
200
|
+
|
201
|
+
実際に発行されたSQLを確認したところ、LEFT JOIN の結合が 1 = 0 となっていました。
|
202
|
+
というかEqualsの先頭にブレイクポイントをはっても止まりませんでしたが… 実装がおかしい?
|
203
|
+
|
204
|
+
```SQL
|
205
|
+
SELECT
|
206
|
+
1 AS [C1],
|
207
|
+
[Extent1].[ID] AS [ID],
|
208
|
+
[Extent2].[StartYmd] AS [StartYmd],
|
209
|
+
[Extent2].[EndYmd] AS [EndYmd]
|
210
|
+
FROM [dbo].[MAIN] AS [Extent1]
|
211
|
+
LEFT OUTER JOIN [dbo].[AAA] AS [Extent2] ON 1 = 0
|
212
|
+
```
|
213
|
+
|
126
214
|
###一応考えた方法
|
127
215
|
|
128
216
|
Where 句で見る…? というのを一応考えたのですが、他に方法がないものかと思い質問させて頂きました。
|