剃刀。 @foreach语句无法运行,因为不包含GetEnumerator的公共定义

时间:2014-11-04 00:51:13

标签: c# asp.net-mvc asp.net-mvc-4 razor

据我所知,与IEnumerator相同的IQueryable都包含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。 附:以下是模型:

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; }
    }

P.P.S。父ViewModel:

<div class="col-md-12">
        @Html.Partial("~/Views/comments/Details.cshtml", new BlogAspNetMVC.Models.comments())
    </div>

3 个答案:

答案 0 :(得分:3)

您似乎错过了添加注释类模型定义。

试试这个......

@model IEnumerable<BlogAspNetMVC.Models.comments>

当Model需要迭代时,comments类应该实现IEnumerable / IQueryable接口,在这种情况下它没有实现。或者局部视图应该将IEnumerable / IQueryable对象作为模型。

您必须将List传递给局部视图渲染(模型绑定)才能解决问题。

这是我尝试过的,它对我有用。

Controller应将IQueriable对象传递给视图

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

在父视图中(呈现局部视图)应使用@model指令作为

@model IQueryable<WebApplication1.Models.comments>

我在局部视图中将@model指令修改为

@model IQueryable<WebApplication1.Models.comments>

尝试一次,它应该有用。

答案 1 :(得分: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; }
}

对于c# naming conventions,您应该将它们重命名为Comment(单数,大写)和BlogPost(大写且无下划线)以及ICommentRepository或类似的接口。 CommentRepository实现的不是comments

您使用的@model应为IEnumerable(或IQueryable),这就是您收到错误的原因。

@model IEnumerable<BlogAspNetMVC.Models.Comment>

GetEnumerator是&#34; Lists&#34;的一种方法。对象,例如IEnumerable,这就是Razor生气的原因,你告诉它你的模型是一个单一的实体(BlogAspNetMVC.Models.comments)(即使你从视图中传入一个数组),所以它类型安全检查失败。命名约定在这里有帮助,因为您有一个Comment而不是数组(注释)

答案 2 :(得分:1)

首先需要了解IEnumerable和IQueryable在内存中的行为之间的区别。

IEnumerable的内存和性能都比较昂贵,因为它会将所有内容加载到内存中,因此您可以跟踪其值,这不是性能的好选择。

IQueryable在内存中创建一个查询,该查询指向您的数据,但它没有您的数据,没有任何内容加载到内存中,因此您无法跟踪它,除非您将部分或全部查询数据加载到内存中

如果您希望将数据查看到页面(如网格或列表),您可以从IQueryable中获益,您需要做的就是选择部分数据并从源上传(可能是数据库)使用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 
}