LinqToSql -. Содержит первичный ключ из нескольких столбцов из списка в памяти, содержащего первичные ключи. - PullRequest
1 голос
/ 24 августа 2011

На клиенте у меня есть анонимный список, содержащий первичный ключ из нескольких столбцов, ранее выбранный из БД.

Затем мне нужно выбрать все записи из БД, которые равны списку первичных ключей, которые я сохранил в памяти.

Я думаю, что приведенный ниже (упрощенный) пример даст вам представление о том, что я пытаюсь архивировать, и, как вы можете видеть, я уже нашел способ, но я надеялся, что у кого-то есть лучшее решение?: -)

.NET пример:

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 = value
        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:

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)

(я извиняюсь, если было опубликовано SO-решение для этой конкретной проблемы, я просто не смог его найти / или понять)

1 Ответ

0 голосов
/ 24 августа 2011

Когда у меня были динамические операторы where, подобные этим, я с большим успехом использовал LINQkit.

http://www.albahari.com/nutshell/linqkit.aspx

Вы хотите проверить построитель предикатов.

...