FluentNHibernate: снижение производительности при сопоставлении ссылки с NotFound.Ignore () - PullRequest
3 голосов
/ 25 февраля 2011

Я использую FluentNhibernate и вижу, как NHibernate выполняет много запросов, когда ссылки на ассоциации отображаются с NotFound.Ignore().

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

Пример:

//no query when loading the entity
References<User>(x => x.User, "UserId").LazyLoad().Nullable();

//performs a hundred queries when I load my entities
References<User>(x => x.User, "UserId").LazyLoad().Nullable().NotFound.Ignore();

1 Ответ

6 голосов
/ 25 февраля 2011

Это известная проблема, к сожалению, есть проблема в NHibernate JIRA (https://nhibernate.jira.com/browse/NH-1001)

Хотя есть обходной путь, но он не очень хорош. В сущности вам нужно сделать что-то вроде этого:

class Entity {

    private int? _userId;

    private User user;

    public User User 
    {
        get { 
            if (_userId == null)
                return null;

            return user;                
        };
        set {
            if (value == null)
                _userId = null;
            else
                _userId = value.UserId;

            _user = value;
        };
    }
 }

И в сопоставлении вы бы отобразили ссылку как обычную, но без установки not-found = ignore, но вы также сопоставили поле внешнего ключа:

 References<User>(Reveal.Membmer<User>("_user"), "UserId").LazyLoad();
 Map(Reveal.Membmer<int?>("_userId")).Nullable().Not.Update().Not.Insert(); // Suppress updates and inserts so that they don't conflict with the mapping of User.

По сути, вы разрешаете NHibernate работать в обычном режиме в поле _user, а затем используете поле _userId, чтобы вручную выполнить проверку нуля. Таким образом, вы избежите проблемы выбора N + 1. Недостатком является то, что это усложняет сущность и усложняет написание запросов. Если вы хотите использовать, например, свойство User в запросе LINQ, вам нужно будет открыть внутреннее поле _user и использовать его вместо этого.

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