LinqToSql - .Contains on multi-column primary key from an in-memory list containing the primary keys
On a client i have an anonymous list containing a multi-column primary key previously selected from the DB.
Then i need to select all the records from the DB that equals the primary key list i have stored in the memory.
I think the below (simplified) example will give you an idea of what i am trying to archive and as you can see i already found a way, but i was hoping somebody had a better solution? :-)
.NET example:
Sub findKeys()
Dim clientLst As New List(Of PriKeys)
clientLst.Add(New PriKeys With {.p = 1, .i = 2})
clientLst.Add(New PriKeys With {.p = 3, .i = 1})
Using DC As New LTSQDataContext
Dim p_lst = clientLst.Select(Function(x) x.p).ToList
Dim i_lst = clientLst.Select(Function(x) x.i).ToList
Dim concLst As New List(Of String) ' used for example 2/3
clientLst.ForEach(Sub(v) concLst.Add(v.p & "|" & v.i))
'1: Wrong - returns row 1,1 (just had to try)
Dim try1 = (From q In DC.TestTbl1s
Where p_lst.Contains(q.p) AndAlso i_lst.Contains(q.i)
Select q.p, q.i).ToList
'2: Works! - but extremely slow as you can imagine
Dim try2 = (From q In DC.TestTbl1s
Where concLst.Contains(q.p & "|" & q.i)
Select q).ToList
'3: Works! - much faster that example 2, but requires double DB call, and returns unnecessary data.
Dim try3tmp = (From q In DC.TestTbl1s
Where p_lst.Contains(q.p)
Select q).ToList
Dim try3 = (From q In try3tmp
Where concLst.Contains(q.p & "|" & q.i)
Select q).ToList
'4: Any better solutions ???
End Using
End Sub
Class PriKeys 'Class to hold the clients primary key collection
Private _p As Integer
Public Property p() As Integer
Get
Return _p
End Get
Set(ByVal value As Integer)
_p = valu开发者_开发知识库e
End Set
End Property
Private _i As Integer
Public Property i() As Integer
Get
Return _i
End Get
Set(ByVal value As Integer)
_i = value
End Set
End Property
End Class
SQL test data:
CREATE TABLE TestTbl1 (p int, i int)
INSERT INTO TestTbl1 VALUES(1,1)
INSERT INTO TestTbl1 VALUES(1,2)
INSERT INTO TestTbl1 VALUES(1,3)
INSERT INTO TestTbl1 VALUES(2,1)
INSERT INTO TestTbl1 VALUES(3,1)
(i apologize if an SO solution for this particular issue has been posted, i just couldn't find it/or understand it)
When I've had dynamic where statements like this I've used LINQkit with great success.
http://www.albahari.com/nutshell/linqkit.aspx
You want to check out the predicate builder.
精彩评论