У меня есть требование, чтобы загрузить сложный объект, называемый Node ... ну его не то, что комплекс ... это выглядит следующим образом: -Нетерпеливый Loading Использование Fluent NHibernate/NHibernate & Автоотображение
Узел имеет ссылку на EntityType который имеет один ко многим с собственности, которая в свою очередь, имеет один ко многим с PorpertyListValue
public class Node
{
public virtual int Id
{
get;
set;
}
public virtual string Name
{
get;
set;
}
public virtual EntityType Etype
{
get;
set;
}
}
public class EntityType
{
public virtual int Id
{
get;
set;
}
public virtual string Name
{
get;
set;
}
public virtual IList<Property> Properties
{
get;
protected set;
}
public EntityType()
{
Properties = new List<Property>();
}
}
public class Property
{
public virtual int Id
{
get;
set;
}
public virtual string Name
{
get;
set;
}
public virtual EntityType EntityType
{
get;
set;
}
public virtual IList<PropertyListValue> ListValues
{
get;
protected set;
}
public virtual string DefaultValue
{
get;
set;
}
public Property()
{
ListValues = new List<PropertyListValue>();
}
}
public class PropertyListValue
{
public virtual int Id
{
get;
set;
}
public virtual Property Property
{
get;
set;
}
public virtual string Value
{
get;
set;
}
protected PropertyListValue()
{
}
}
Что я пытаюсь сделать, это загрузить объект Node со всеми дочерними объектами одновременно. Нет ленивой нагрузки. Причина в том, что у меня есть тысячи объектов Node в базе данных, и я должен отправить их по проводу с помощью службы WCF. Я столкнулся с проблемами SQL N + 1 классов. Я использую Fluent Nhibernate с Automapping и NHibernate Profiler, предложил мне использовать FetchMode.Eager для загрузки всего объекта сразу. Я использую следующий qyuery
Session.CreateCriteria(typeof (Node))
.SetFetchMode("Etype", FetchMode.Join)
.SetFetchMode("Etype.Properties", FetchMode.Join)
.SetFetchMode("Etype.Properties.ListValues", FetchMode.Join)
ИЛИ с помощью NHibernate LINQ
Session.Linq<NodeType>()
.Expand("Etype")
.Expand("Etype.Properties")
.Expand("Etype.Properties.ListValues")
Когда я запускаю любой из выше запроса, оба они генерируют один такой же один запрос со всеми левого внешнего соединения, которое является то, что Мне нужно. Однако по какой-то причине возврат запроса ILIS из запроса не загружается в объекты. Infact возвращаемое количество узлов равно количеству строк запроса, поэтому объекты Nodes повторяются. Кроме того, свойства внутри каждого узла повторяются, а также значения Listvalues.
Поэтому я хотел бы знать, как изменить указанный выше запрос, чтобы вернуть все уникальные узлы со свойствами и значениями в них.
Благодаря Набиль
На гугле я узнал о DistinctRootEntityResultTransformer но , которые разрешают проблему только для объектов Root. Я все еще получаю дубликаты в дочерних коллекциях . Каждый корневой объект в возвращаемом списке имеет некоторые странные декартовы беспорядки в дочерних коллекциях с несколькими экземплярами одного и того же объекта. Есть идеи? Ожидание Nabeel – nabeelfarid
Я думаю, что нашел решение, но я хотел бы знать, правильно ли он соответствует . Детские коллекции (EType.Properties, Etype.Properties.ListValues) внутри корневого объекта (Узел) являются IList. И я прочитал в документации , что IList может содержать дубликаты, поэтому, если я изменяю IList на ISet/ ICollection, тогда запрос не загружает дубликаты экземпляров в пределах дочерних коллекций. Но для этого решения требуется много рефакторинга. Я хотел бы знать , если есть способ добиться того же, используя IList для дочерних коллекций? Ожидание, Nabeel – nabeelfarid
У меня такая же проблема (с использованием Fetchmode.Eager). Для этого я довольно разочарован в NHibernate. Я бы предпочел ошибку, чем неверные данные. – UpTheCreek