ASP.NET MVC Проблемы с получением данных и связанных данных в представление. (Просмотреть образец модели?)

У моего сайта есть пользователи. На моем сайте есть предметы. Пользователи могут оставить отзыв о товаре. Пользователи могут оставить рейтинг предмета. Когда пользователи оценивают элемент, они оценивают его по разным категориям: оценка качества сборки, оценка полезности, оценка эстетической привлекательности.

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

Теперь на моей странице элемента я хочу отобразить десять последних обзоров и оценок.

Как я могу получить обзоры и соответствующие рейтинги и отправить их все в представление для отображения?

(Я использую LINQ to SQL).

Спасибо.

РЕДАКТИРОВАТЬ: Извините, я думал, что включил достаточно информации. Вот еще немного информации о моей базе данных. Допустим, на моем сайте есть разные предметы. Скажем, он содержит информацию об автомобилях и книгах. Очевидно, что при оценке автомобиля у вас другие критерии, чем при оценке книги.

Я помещаю все свои рейтинговые данные в одну рейтинговую таблицу.

У меня есть таблица RatingsCategories. Он содержит две колонки:

RatingCategoryID  (Identity column)
RatingCategory    (name of category)

Категория «Обложка» применима к книгам. Категория «Производительность» применима к автомобилям.

У меня есть таблица рейтингов. Он содержит следующие столбцы:

RatingID  (Identity column)
EntityID  (Unique identifier among Cars AND Books)
UserID    (Identifier of the user who left the rating)
RatingCategoryID  (Reference to the category; FK from the RatingsCategories table)
Rating    (int;  the rating given)
DateModified (DateTime)

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

Точно так же моя таблица обзоров может содержать обзоры книг и автомобилей. Выглядит это так:

ReviewID  (Identity column)
EntityID  (Unique identifier among Cars AND Books)
UserID    (Identifier of the user who left the rating)
Body      (Text of review)
DateModified  (DateTime)

Пользователь может оценить и просмотреть каждый элемент один раз. Итак, если посетитель сайта переходит на страницу книги, я хочу отобразить последние 10 обзоров и соответствующие рейтинги. Это означает, что мне нужно взять 10 последних рецензий на эту Книгу. Мне также нужно получить десять самых последних полных оценок для этой книги (тот же EntityID и тот же идентификатор пользователя, что и у обзоров), которые могут быть тремя записями для каждой оценки.

Имеет ли это смысл?

Как лучше всего это сделать?

Я сумасшедший в таком подходе и схеме базы данных?

Спасибо за терпеливость.


person johnnycakes    schedule 23.07.2010    source источник
comment
Вам нужно будет показать классы вашей модели.   -  person Darin Dimitrov    schedule 23.07.2010
comment
Вам следует подумать об использовании соединительных таблиц для хранения мета рейтинга. Рейтинговая запись должна просто знать о рейтинге. Используйте таблицу, например ItemRatings, для хранения метаданных, например UserId и EntityId. Это должно немного упростить сложные таблицы.   -  person Steven Hook    schedule 23.07.2010


Ответы (2)


Здесь особо не о чем говорить, но я сделаю несколько предположений и попытаюсь ответить на ваш вопрос.

Предположения:

  1. Если вы используете LINQ to SQL, вы, вероятно, используете шаблон репозитория.
  2. Вы используете структуру реляционной базы данных, которая будет включать таблицы для привязки элементов к обзорам и элементов к рейтингам.
  3. Я как бы догадываюсь, какой будет у вас структура базы данных.

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

<div class="latest-reviews-ratings">
    <% Html.RenderPartial("ReviewsAndRatings", Model.Reviews); %>
</div>

Тогда ваша деталь может выглядеть так, как вы хотите ...

<div class="reviews">
    <% foreach (var reviewModel in Model) {%>
        <div class="review">
            Review of: <i><%: reviewModel.Item.Name %></i> by <b><%: reviewModel.Reviewer.Username %></b>.
            <div><%: reviewModel.Review.Value %></div>

            <ul class="ratings">
                <% foreach (var ratingModel in reviewModel.Ratings) {%>
                    <li>
                        <b><%: ratingModel.Rater.Username %></b> rated this a <%: ratingModel.Rating.Value %> on <%: ratingModel.Rating.CategoryName %>.
                    </li>
                <% } %>
            </ul>
        </div>
    <% } %>
</div>

Ваша модель представления может выглядеть так:

public class IndexViewModel
{
    public IEnumerable<ReviewViewModel> Reviews { get; set; }
}

ReviewViewModel может выглядеть так:

public class ReviewViewModel
{
    public User Reviewer { get; set; }
    public Item Item { get; set; }
    public Review Review { get; set; }
    public IEnumerable<RatingViewModel> Ratings;
}

RatingViewModel:

public class RatingViewModel
{
    public User Rater { get; set; }
    public Rating Rating { get; set; }
}

Теперь все, что вам нужно сделать, это подключить его к контроллеру. Вытащите свои записи ItemReview и создайте из них модели представлений.

var itemReviews = _itemReviewRepository.FindAll().OrderByDescending(p => p.Review.DateAdded).Take(10);
var reviewViewModels = itemReviews.Select(p =>
    new ReviewViewModel
    {
        Item = p.Item,
        Reviewer = p.User,
        Review = p.Review,
        Ratings = ReviewRatingService.GetRatingViewModelForReview(p.ReviewId)
    });

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

return (from rating in dataContext.Ratings
        join itemRating in dataContext.ItemRatings
            on rating.Id equals itemRating.RatingId
        join itemReview in dataContext.ItemReviews
            on itemRating.ItemId equals itemReview.ItemId
        join review in dataContext.Reviews
            on itemReview.ReviewId equals review.Id
        where review.Id == reviewId
        select new RatingViewModel
                {
                    Rater = itemRating.User,
                    Rating = rating
                });

Теперь вы можете заполнить модель представления индекса этими данными.

var model = new IndexViewModel
{
    Reviews = reviewViewModels
};

и верните основную модель на ваш вид.

return View(model);

Я только что написал веб-приложение. На самом деле это было довольно весело.

person Steven Hook    schedule 23.07.2010
comment
Спасибо за ответ, но похоже, что вы собираете обзоры и рейтинги независимо, не задумываясь о том, соответствуют ли они друг другу ...? Дайте мне знать, если я читаю неправильно; Я все еще учусь. Также, пожалуйста, посмотрите мою правку. Спасибо. - person johnnycakes; 23.07.2010
comment
Мне было непонятно, могу ли я предположить, что все обзоры будут иметь оценки, и что вы можете получить оценки, только создав обзор. Я посмотрю, смогу ли я что-нибудь обновить. - person Steven Hook; 23.07.2010
comment
Я только что обновил. Общий характер ваших элементов может усложнить вам остальную часть приложения, но я действительно не думаю, что это повлияет на вас, когда вы просто отображаете данные, поэтому вам могут помочь некоторые варианты этого решения. - person Steven Hook; 23.07.2010
comment
Я думаю, что это все. Большое спасибо! - person johnnycakes; 24.07.2010
comment
Привет, надеюсь, это не слишком просто, но не могли бы вы дать мне полный пример того, как реализовать класс обслуживания? Я новичок в этом деле. Я искал в Google, но не нашел ничего стоящего. Спасибо. - person johnnycakes; 24.07.2010
comment
@johnnycakes Я только что создал статический класс с помощью статического метода public static IQueryable ‹RatingViewModel› GetRatingViewModelForReview (int reviewId). Затем создайте новый _dataContext с типом, полученным от LinqToSql, и используйте этот построенный запрос linq в моем сообщении. - person Steven Hook; 26.07.2010

Без дополнительной информации я предполагаю, что что-то вроде этого сработает:

Item.Reviews.OrderByDescending(d => d.date).Take(10)
person jwsample    schedule 23.07.2010