Ранее я задавал вопрос относительно моделирования ситуации с Users, Items и UserRatings. В моем примере UserRatings связаны с одним пользователем и одним Item. Хороший ответ дал Натан Фишер, и я включил модель, которую он предложил ниже.
Но теперь у меня есть вопрос относительно поиска этих объектов .
Модель связывает сущности, удерживая ссылки на сущности. Мой вопрос таков: как лучше всего получить конкретный UserRating для обновления? В этой ситуации У меня будет идентификатор пользователя (из сеанса аутентификации asp.net), и itemID (из URL). Кроме того, может быть 1000 оценок на пользователя или элемент.
В прежней школе это было бы так же просто, как один запрос на обновление, где x = userID и y = itemID. Легко. Однако лучший способ добиться этого в NHibernate с использованием правильной объектной модели не так ясен.
A) Я понимаю, что мог бы создать метод репозитория GetRatingByUserAndItem и передать ему как объект User, так и объект Item, для чего он будет выполнять запрос HQL / критерии для получения объекта Rating . Однако для этого я предполагаю, что сначала мне нужно будет извлечь пользователя и элемент из ORM, а затем передать их обратно в ORM в запросе. Затем я получу объект UserRating, обновлю его, а затем ORM сохранит изменения. Это кажется мне смехотворно неэффективным по сравнению с методом старой школы.
B) Может быть, я мог бы просто обновить объект UserRating и выполнить тип createorupdate, вызвав ORM (не уверен в точном синтаксисе). Это было бы лучше, но по-видимому, мне все равно нужно было бы сначала получить пользователя и элемент, который все еще довольно неэффективен.
C) Возможно, мне следует просто извлечь пользователя (или элемент) из ORM и найти правильный UserRating из его коллекции UserRatings. Однако, если я это сделаю, как мне убедиться, что я не получаю все UserRatings, относящиеся к этому пользователю (или элементу), а только тот, который относится к конкретному элементу и конкретному пользователю?
D) Мне пришло в голову, что я могу просто отбросить полномасштабные ссылки на User и Item из UserRating в модели и вместо этого иметь примитивные ссылки (UserID и ItemID). Это позволило бы мне сделать что-то столь же простое, как метод oldschool. Очень заманчиво, но мне это не кажется правильным - не очень объектно-ориентированным (и, конечно, это главная причина, по которой мы используем ORM в первую очередь!)
Итак, кто-нибудь может дать совет мудреца? Я на правильном пути с любым из вариантов выше? Или есть лучший способ, который я не рассмотрел?
Спасибо заранее за вашу помощь! :)
UPDATE:
Я только что опубликовал награду за это и лучше понимаю, Я также хотел бы узнать, используя аналогичный подход, как лучше выполнить следующие запросы :
- Получить все элементы, которые пользователь НЕ оценил.
- Извлечение предмета (ов) и рейтинга (ов) предметов, которые пользователь оценил самым низким.
Модель следует ниже:
public class User
{
public virtual int UserId { get; set; }
public virtual string UserName { get; set; }
public virtual IList<UserRating> Ratings { get; set; }
}
public class Item
{
public virtual int ItemId { get; set; }
public virtual string ItemName { get; set; }
public virtual IList<UserRating> Ratings { get; set; }
}
public class UserRating
{
public virtual User User { get; set; }
public virtual Item Item { get; set; }
public virtual Int32 Rating { get; set; }
}
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Test" namespace="Test" >
<class name="User">
<id name="UserId" >
<generator class="native" />
</id>
<property name="UserName" />
<bag name="Ratings" generic="true" inverse="true" table="UserRating">
<key column="UserId" />
<one-to-many class="UserRating"/>
</bag>
</class>
<class name="Item" >
<id name="ItemId" >
<generator class="native" />
</id>
<property name="ItemName" />
<bag name="Ratings" generic="true" inverse="true" table="UserRating">
<key column="ItemId" />
<one-to-many class="UserRating"/>
</bag>
</class>
<class name="UserRating" >
<composite-id>
<key-many-to-one class="User" column="UserId" name="User" />
<key-many-to-one class="Item" column="ItemId" name="Item" />
</composite-id>
<property name="Rating" />
</class>
</hibernate-mapping>