Средний метод сначала не работает с основным кодом asp.net: - PullRequest
0 голосов
/ 07 мая 2018

2 модели классов:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations;

namespace CareCompProj.Models
{
public enum Profession { Counsellor, Physio, Doctor }
public class HealthProfessional
{
    public int ID { get; set; }
    [Required]
    [StringLength(50)]
    [Display(Name = "Name")]
    public string Name { get; set; }
    public bool AcceptsMedicalCard { get; set; }
    [Required]
    [StringLength(80)]
    [Display(Name = "Address")]
    public string Address { get; set; }
    [Required]
    public Profession Profession { get; set; }
    public ICollection<Review> HealthReviews { get; set; }

    public double CalculateAverageRating()
    {
        var averageRating = HealthReviews.Average(r => r.Rating);


        return averageRating;
    }
    public ICollection<Client> Clients { get; set; }
    }
}




using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations;

namespace CareCompProj.Models
{
public class Review
{
    public int ID { get; set; }
    public int? ClientID { get; set; }
    public int? HealthProfessionalID { get; set; }
    [Required]
    [Range(0, 5, ErrorMessage = "Please select number between 1 and 5")]
    public int Rating { get; set; }


    [Required]
    public string ReviewText { get; set; }
    public bool WouldRecommend { get; set; }
    public virtual Client Client { get; set; }
    public HealthProfessional HealthProfessional { get; set; }
  }
}

Мои 2 проблемы

  1. когда я использую метод, созданный в классе Healthprofessional, я получаю ArgumentNullException: значение не может быть нулевым. Имя параметра: источник

например,

@foreach (var item in Model){
<p> @item.CalculateAverageRating() </p>
}
  1. если я использую ViewBag, созданный в методе контроллера Healthprofessional Index. Это возвращает Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable 1[<>f__AnonymousType2 2 [CareCompProj.Models.HealthProfessional, System.Double]]

Когда я перехожу на страницу URL, где должен быть рейтинг.

Вот ViewBag (созданный в методе индекса Healthprofessional controller), на который я ссылаюсь в виде бритвы при попытке получить средний рейтинг

 ViewBag.profRatings = _context.HealthProfessionals.Include(p => p.HealthReviews)

 ViewBag.profRatings = _context.HealthProfessionals.Include(p => p.HealthReviews)
                              .Select(x => new
                              {
                                  HealthProfessional = x,
                                  RatingAverage = x.HealthReviews.Any() ?
                                  x.HealthReviews.Average(v => (v.Rating)) : 0
                              });

Используется индекс индекса бритвы для медицинских работников

@model IEnumerable<CareCompProj.Models.HealthProfessional>

Любая помощь по этому вопросу будет принята с благодарностью. Спасибо

1 Ответ

0 голосов
/ 07 мая 2018

На самом деле вам нужно материализовать результат, вызвав ToList() в действии вашего контроллера перед установкой в ​​ViewBag или вернувшись назад из запроса, используя return View(model), чтобы запрос выполнялся и набор результатов заполнялся в памяти в List<T>.

Итак, для вашего запроса linq:

var model = _context.HealthProfessionals.Include(p => p.HealthReviews)
                          .Select(x => new
                          {
                              HealthProfessional = x,
                              RatingAverage = x.HealthReviews.Any() ?
                              x.HealthReviews.Average(v => (v.Rating)) : 0
                          }).ToList();

Теперь либо передайте его обратно для просмотра при возврате, как:

return View(model);

или вы можете установить ViewBag.profRatings и затем использовать его в поле зрения.

UPDATE:

вы можете создать ViewModel, специфичную для ваших требований к представлению, например:

public class HealthProfessionalVM
{

   public HealthProfessional HealthProfessional { get; set; }
   public int RatingAverage { get ;set; }
}

и затем заполните его в действии контроллера вместо создания анонимного объекта:

var vm = _context.HealthProfessionals.Include(p => p.HealthReviews)
                          .Select(x => new HealthProfessionalVM
                          {
                              HealthProfessional = x,
                              RatingAverage = x.HealthReviews.Any() ?
                              x.HealthReviews.Average(v => (v.Rating)) : 0
                          }).ToList();

return View(vm);

и теперь строго наберите ваш взгляд на IEnumerable<HealthProfessionalVM> и итерируйте его как:

@model IEnumerable<HealthProfessionalVM>

foreach(var item in Model) 
{ 
   <p> @item.RatingAverage </p>
}

Надеюсь, это поможет.

...