исключение запроса nHibernate: строки с данным идентификатором не существует - PullRequest
2 голосов
/ 06 октября 2011

После небольшого изменения модели данных некоторые запросы начали давать мне это исключение.Однако даже после прочтения различных веток форума и блогов я не понимаю, почему это происходит в моем случае.Поэтому я надеюсь, что кто-то здесь может помочь.Во-первых, пример запроса:

var criteria = Session.CreateCriteria(typeof(SomeEntity));
        criteria.Add(Expression.IdEq(id));
        criteria.SetFetchMode("_PrivateProperty", FetchMode.Eager);
        criteria.CreateAlias("PublicProperty", "alias");
        criteria.Add(Expression.Eq("alias.Id", aliasId));

Если я изменю запрос, удалив (1) SetFetchMode или (2) CreateAlias ​​для открытого свойства, все работает нормально.

Закрытое свойствообычно загружается лениво, но в этом случае я хочу загрузить его вместе с его родительским объектом для борьбы с выбором N + 1.

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

ОБНОВЛЕНИЕ

Сгенерированный SQL:

SELECT * FROM SomeEntity this_ 
inner join PublicProperty alias4_ on this_.SomeEntityId=alias4_.SomeEntityId 
inner join ReferencedProperty rp2_ on alias4_.RPId=rp2_.RPId 
left outer join PrivateProperty v1_ on this_.SomeEntityId=v1_.SomeEntityId 
WHERE this_.SomeEntityId= @p0 and rp2_.RPId= @p1

При запуске в SQL Server Management Studio он работает должным образом,Я получаю два результата.Между модификацией модели данных и запроса данные в базе данных не изменились.

UPDATE2

Изменение в модели.Оригинальное отображение:

References(d => d.PublicProperty, "PublicPropertyId").Cascade.SaveUpdate();

Новое отображение:

HasManyToMany(d => d.PublicPropertys)
            .Access.CamelCaseField(Prefix.Underscore)
            .Table("SomeEntityPublicProperty")
            .ParentKeyColumn("SomeEntityId")
            .ChildKeyColumn("PublicPropertyId")
            .Cascade.SaveUpdate()
            .Inverse();

ОБНОВЛЕНИЕ3

HasMany<PrivatePropertyEntity>(Reveal.Member<SomeEntity>("_PrivateProperty"))
            .Table("SomeEntity_PrivateProperty")
            .KeyColumn("SomeEntityId")
            .Cascade.AllDeleteOrphan()
            .LazyLoad().Inverse();

1 Ответ

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

Ваша проблема, вероятно, связана с тем, что если вы используете createalias (без указания внешнего типа соединения), сущности не загружаются с нетерпением, несмотря на то, что ваша конфигурация.

Причина этого связана с вашей ошибкой: при условии, что вы не указали никаких критериев для RHS ассоциации и у вас есть нулевые ссылки в ваших данных, использование INNER JOIN неправильно отфильтровывает записи в LHS.

Таким образом, для NHibernate не имеет значения, что ваш запрос возвращает два результата, используя ВНУТРЕННИЕ СОЕДИНЕНИЯ, он все равно идет вперед и лениво загружает ассоциации. Где-то у вас есть ссылка на несуществующее свойство, на которое есть ссылки, в вашей таблице соединений "многие ко многим", и оно терпит неудачу, когда пытается лениво загрузить его, чтобы проверить, соответствует ли RHS вашим критериям.

Изменение псевдонима для выполнения левого внешнего соединения должно предотвратить ошибку (она действительно будет загружать связанные сущности с нетерпением и не будет перепроверять ссылки), но у вас все равно будет проблема ссылочной целостности где:

criteria.CreateAlias("PublicProperty", "alias", JoinType.LeftOuterJoin);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...