Таблица связывания NHibernate с данными - PullRequest
1 голос
/ 27 октября 2011

SQL 2008 | .NET 4.0 | NHibernate 3.1 | NHibernate.Castle 3.1 | Castle.Core 2.5.2

Итак, у меня есть таблица связей с метаданными, как и автор этого вопроса NHibernate Отображение многих ко многим с данными в таблице соединений

Изначально я составил карту так же, как и ответ на этот вопрос, поскольку он казался самым экономным способом справиться с этим. Однако после включения show_sql и наблюдения за тем, что происходило, поиск идентификаторов в итоге дал N + 1 запросов, где N - количество ассоциаций.

Обратите внимание на этот пример базы данных, которая аналогична моим фактическим данным, определенным в sql-подобном синтаксисе

CREATE TABLE [User] 
(
  Id int PRIMARY KEY 
)

CREATE TABLE UserPref 
(
  Id int PRIMARY KEY,
  Name varchar(32)
)

CREATE TABLE UserPrefAssociation 
(
  UserId int,
  PrefId int,
  Value varchar(32)
)

Я взломал следующий код вместе с этим сопоставлением объектов «один ко многим» этого пользователя IList<UserPrefAssociation> Preferences { get; set; }

    public IDictionary<string, string> GeneratePrefDict()
    {
        return Preferences
            .ToDictionary(i => i.UserPref.Name, i => i.Value);
    }

Конечно, это прекрасно работает, но, как упоминалось ранее, каждый i.UserPref.Name является дополнительным запросом к SQL.

После игры в SQL я нашел запрос, который выполняет то, что я хочу. Тогда у меня возникает вопрос: как я могу это сделать с помощью NHibernate?

SELECT UserPref.Name, UserPrefAssociation.Value
FROM [User] 
    INNER JOIN UserPrefAssociation ON [User].Id = UserPrefAssociation.UserId
    INNER JOIN UserPref ON UserPrefAssociation.UserPrefId = UserPref.Id
WHERE [User].Id = 1

~~~~ решаемый ~~~~~

    using NHibernate.Linq;
    ...
    public IDictionary<string, string> GeneratePrefDict(ISession s)
    {
        return 
            (from entry in s.Query<User_UserPref>()
             where entry.User == this
             select new
             {
                 key = entry.UserPref.Name,
                 value = entry.Value
             })
             .ToDictionary(i => i.key, i => i.value);
    }

Создает этот SQL

NHibernate: select userpref1_.Name as col_0_0_, user_userp0_.Value as col_1_0_ f
rom User_UserPref user_userp0_ left outer join UserPref userpref1_ on user_userp
0_.UserPrefId=userpref1_.Id where user_userp0_.UserId=@p0;@p0 = 1 [Type: Int32 (
0)]

Это лучше, чем N + 1 запросов, и решает мою проблему.

1 Ответ

0 голосов
/ 28 октября 2011

Я думаю, что вы можете достичь того, что вы хотите с Futures и QueryOver. Взгляните на следующую статью:

Борьба с декартовым произведением (x-join) при использовании NHibernate 3.0.0

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...