Бритва. Оператор @foreach не может работать, потому что не содержит публичного определения для GetEnumerator

1

Поскольку я знаю, что IQueryable такой же, как IEnumerator, содержит метод GetEnumerator, но когда я перехожу к частичному объекту IQueryable, Razor сказал, что для GetEnumerator нет определения. Вот определение интерфейса:

 public interface IComments : IDisposable
    {
        IQueryable<comments> GetPostComments(int postid);
        //void Add(comments comment);
        //void Update(comments comment);
        //void Remove(int id);
    }

Вот репозиторий:

 public class CommentsRepository: IComments, IDisposable
    {
        private blogaspnetEntities db;
        public CommentsRepository(blogaspnetEntities db)
        {
            this.db = db;
        }
        public IQueryable<comments> GetPostComments(int postid)
        {
            var all = from a in db.comments
                      orderby a.Posted descending
                      where a.PostID == postid
                      select a;
            return all;
        }
        private bool disposed = false;

        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                if (disposing)
                {
                    db.Dispose();
                }
            }
            this.disposed = true;
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
    }

И, наконец, частичный вид:

@model BlogAspNetMVC.Models.comments

<div class="row">
    @foreach (var item in Model)
    {
        <div class="col-md-12">
            <div class="panel panel-default">
                <div class="panel-heading">
                    <h3 class="panel-title">@item.Author " сказал " @item.Posted ":"</h3>
                </div>
                <div class="panel-body">
                    @Html.Raw(HttpUtility.HtmlDecode(@item.Comment))
                </div>
            </div>
        </div>
    }
</div>

Я действительно не могу понять, что неправильно, потому что, как видите, все это IQuerybale. PS И вот модель:

public partial class comments
    {
        public int ID { get; set; }
        public string Comment { get; set; }
        public Nullable<int> Author { get; set; }
        public Nullable<System.DateTime> Posted { get; set; }
        public Nullable<int> PostID { get; set; }

        public virtual blog_post blog_post { get; set; }
    }

PPS Parent ViewModel:

<div class="col-md-12">
        @Html.Partial("~/Views/comments/Details.cshtml", new BlogAspNetMVC.Models.comments())
    </div>
  • 2
    Если вы моделируете IComments , это не IQueryable , у него есть IQueryable .
  • 0
    Я понял, но как мне сменить модель?
Показать ещё 3 комментария
Теги:
razor
asp.net-mvc
asp.net-mvc-4

3 ответа

3
Лучший ответ

Кажется, вас упустили, чтобы добавить определение модели класса комментариев.

Попробуй это...

@model IEnumerable<BlogAspNetMVC.Models.comments>

Когда модели требуется итерация, класс комментариев должен реализовывать интерфейс IEnumerable/IQueryable, в этом случае он не реализован. Или частичное представление должно получить объект IEnumerable/IQueryable в качестве модели.

Чтобы решить проблему, вам необходимо передать список в частичное представление (привязка модели).

Это то, что я пробовал, и это сработало для меня.

Контроллер должен передать объект IQueriable в представление

IQueryable<comments> commentsList = commentsRepository.GetPostComments(1);
        return View(commentsList);

В родительском представлении (которое отображает частичное представление) следует использовать директиву @model как,

@model IQueryable<WebApplication1.Models.comments>

Я изменил директиву @model в частичном представлении,

@model IQueryable<WebApplication1.Models.comments>

Попробуйте один раз, и он должен работать.

  • 0
    Я пропускаю эти методы намеренно. Определенно проблема не здесь.
  • 0
    Это было полезно
1

Сначала вам нужно понять разницу между IEnumerable и IQueryable с точки зрения их поведения в памяти.

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

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

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

IQueryable<Comment> dataquery = _db.Comments;

int pagesize = 20; //20 items to be viewed on each page
int page = 1;
IList commentslist = dataquery.Skip((page - 1) * pagesize).Take(pagesize).ToList();
foreach(Comment cmt in commentslist)
{
    //Here you can trace comments items 
}
1

Несколько вещей, которые запутывают:

public interface IComments : IDisposable
{
    IQueryable<comments> GetPostComments(int postid);
    //void Add(comments comment);
    //void Update(comments comment);
    //void Remove(int id);
}

public partial class comments
{
    public int ID { get; set; }
    public string Comment { get; set; }
    public Nullable<int> Author { get; set; }
    public Nullable<System.DateTime> Posted { get; set; }
    public Nullable<int> PostID { get; set; }

    public virtual blog_post blog_post { get; set; }
}

Для конвенций с именованием С# вы должны действительно переименовать их в Comment (особый, прописный) и BlogPost (прописные и без подчеркивания) и интерфейс к ICommentRepository или что-то подобное, поскольку CommentRepository - это то, что реализует его, а не comments

@model вами @model должен быть IEnumerable (или IQueryable), поэтому вы получаете ошибку.

@model IEnumerable<BlogAspNetMVC.Models.Comment>

GetEnumerator - это метод в "списках" объектов, таких как IEnumerable поэтому Razor безумный, вы говорите, что ваша модель представляет собой единую сущность (BlogAspNetMVC.Models.comments) (даже если вы передаете массив из представления), поэтому проверки типа безопасности не срабатывают. Соглашения об именах помогают здесь, так как у вас есть один Comment не массив (комментарии)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню