据我所知,与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>
答案 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
}