开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜