LinqToSql - избегая чрезмерных запросов к базе данных - PullRequest
2 голосов
/ 27 мая 2009

Этот сценарий часто встречается, теперь, когда я использую LinkToSql и создаваемые им классы.

Классический сценарий - две таблицы:

Член
ID
Имя
...

Членство
ID
MemberID (внешний ключ)
Начало (дата / время)
Срок действия (дата / время)
...

Активное членство будет таким, где сейчас между началом и истечением.

Чтобы узнать, есть ли у пользователя активное членство, я создал этот частичный класс для расширения в генерируемом LinkToSql классе-члене:

Partial Public Class Member
    Public ReadOnly Property HasActiveMembership() As Boolean
        Get
            Dim activeMembershipCount As Integer = (From m In Me.Memberships _
                                Where m.MemberId = Me.MemberId _
                                And m.StartDate < Now And m.ExpirationDate > Now() _
                                Select m).Count

            If activeMembershipCount > 0 Then Return True Else Return False

        End Get
    End Property
End Class

Это прекрасно работает для одного участника, но когда я хочу перечислить 700 участников и, если они имеют активное членство или нет, это делает более 700 вызовов в базу данных.

Как мне изменить свою модель / классы?

Я мог бы создать запрос только для списков, в котором все это можно сделать одним запросом, что довольно просто, но я бы хотел этого избежать, если бы мог.

Ответы [ 2 ]

2 голосов
/ 27 мая 2009

У вас есть несколько вариантов; Например, вы можете использовать DataLoadOptions.LoadWith или DataLoadOptions.AssociateWith для быстрого извлечения данных - однако оптимальный подход зависит от того, как вы его используете.

Например, вы можете написать запрос «пользователи с активным членством» (либо в LINQ, используя Any, либо с помощью SPROC / UDF). Тогда это будет 1 поездка туда и обратно, но, возможно, она будет менее объектно-ориентированной (и более ориентированной на запросы). Что может быть хорошо ...

0 голосов
/ 27 мая 2009

Похоже, у вас уже определена ассоциация, возможно, из-за связи FK между таблицами. В таком случае вы можете просто расширить свой запрос на членство, используя предложение where, используя ссылку на сущность, уже определенную в классе.

C # пример:

var query = db.Members.Where( m => m.Memberships
                                    .Any( ms => ms.StartDate > now
                                                && ms.ExpirationDate < now ));
...