Отображение один ко многим. NHibernate - PullRequest
0 голосов
/ 28 сентября 2011

Я просматривал книгу «Руководство для начинающих по NHibernate 3» и нашел интересный совет:

В реальном приложении для инвентаризации вы, вероятно, захотите избежать размещения коллекции Products в объекте Category,возможно, что категория может иметь сотни, если не тысячи, связанных продуктов.Загружать целую огромную коллекцию продуктов для данной категории было бы неразумно и привело бы к тому, что приложение получило бы неудовлетворительное время отклика.

Совет был сразу после примера построения отношений один ко многим,Объектами были Product и Category.Пример довольно прост:

public class Category : Entity // Entity probably contains an `Id` property
{
    private List<Products> products;

    public String CategoryName { get; set; }
    public String Description  { get; set; }
    public IEnumerable<Product> Products { get { return products; } }
}  

public class Product : Entity
{
    public Decimal UnitPrice { get; set; }
    public String ProductName { get; set; }
    public Category Category { get; set; }
}

Так, каков реальный пример отношений один-ко-многим?

Было бы достаточно для примера просто поместить Category внутрисущность товара как свойство String?

Ответы [ 4 ]

1 голос
/ 01 октября 2011

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

var products = session.QueryOver<Product>().Where(p => p.Category == someCategory).List();

Но теперь у вас есть возможность делать пейджинг, фильтрация, получение лучшего продукта и т. д.:

var product = session.QueryOver<Product>().Where(p => p.Category == someCategory).OrderBy(p => p.Relevance).Take(1).SingleOrDefault();

, которого у вас нет, если это простое свойство IList.В целом (по моему опыту), чем меньше у вас двусторонних ассоциаций, тем лучше будет ваша гранулярность запросов.Кроме того, это уменьшает вашу сложность, когда дело доходит до экономии.

1 голос
/ 29 сентября 2011

Возможно, вы захотите взглянуть на ленивое свойство Nhibernate. Оно позволяет вам не загружать это свойство всегда, если мы явно не запрашиваем его.

Нибернатный Ленивый

0 голосов
/ 29 сентября 2011

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

На самом деле это довольно распространенный сценарий реальной жизни, и один из самых простых подходов - просто иметь свойство Category.Products. Конечно, нет ничего плохого в том, чтобы иметь такое свойство, но реальный вопрос в том, как вы должны управлять этими объектами.

К счастью, вам не нужно тянуть все продукты с одной категорией. Category.Products можно пометить как загрузить лениво (в отличие от с нетерпением , больше информации можно найти здесь ). Это означает, что категория загрузки не будет запрашивать базу данных для своих продуктов. Вместо этого NHibernate создаст прокси объект для Products, который можно инициализировать позже - когда они действительно необходимы (например, пользователь расширяет узел категории).


И чтобы ответить на ваш вопрос ...

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

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

Я думаю, что цитата скажет, что вы вообще не должны использовать свойство Products в классе Category.

...