teratail header banner
teratail header banner
質問するログイン新規登録

質問編集履歴

3

タグを追加 \(LINQ to Entities, Entity Framework\)

2017/02/07 06:44

投稿

sk_3122
sk_3122

スコア1126

title CHANGED
File without changes
body CHANGED
File without changes

2

StackOverflowで見つけた内容

2017/02/07 06:44

投稿

sk_3122
sk_3122

スコア1126

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を実装してみました

2017/02/07 04:16

投稿

sk_3122
sk_3122

スコア1126

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 句で見る…? というのを一応考えたのですが、他に方法がないものかと思い質問させて頂きました。