我有2张桌子:
public class ApplicationUser : IdentityUser
{
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
return userIdentity;
}
[ForeignKey("ApplicationUserId")]
public virtual ICollection<ApplicationUserNotification> ApplicationUserNotifications { get; set; }
}
public class ApplicationUserNotification
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long Id { get; set; }
[StringLength(64)]
public string ApplicationUserId { get; set; }
[ForeignKey("ApplicationUserId")]
public virtual ApplicationUser ApplicationUser { get; set; }
}
我想为用户显示前10条通知,并在用户向下滚动时使用同一视图加载后10条通知。
public ActionResult UserNotications(int skip = 0, int take = 10)
{
var db = new ApplicationDbContext();
var user = db.Users.FirstOrDefault(a => a.Id == User.Identity.GetUserId());
var list = user.ApplicationUserNotifications.Skip(skip).Take(take).ToList();
return View(list);
}
可是说:
'ICollection'不包含'Skip'的定义,最佳扩展方法重载'Queryable.Skip(IQueryable,int)'需要类型为'IQueryable'的接收器
在不更改代码以直接从用户通知表中查询的情况下,解决此问题的最佳方法是什么?该代码的实际用法使用用户类,因此,如果我可以通过用户对象访问用户通知,那就更好了。
我原本以为会有很多问题,但是搜索引擎似乎跳过了“跳过”一词,所以我对此一无所知。
====================
mick的更新,我在视图中使用它,并且有一个静态对象,可以在其中访问名为“当前”的用户对象:
@{
Layout = null;
var skip = Convert.ToInt32(Request["Skip"] ?? "0");
var take = Convert.ToInt32(Request["Take"] ?? "10");
}
@foreach (var item in Current.User.UserNotifications.Skip(skip).Take(take))
{
@Html.Partial(Enum.GetName(typeof(Kiteshoot.Enums.NotificationType), item.NotificationType), item)
}
<div class="UserNotificationsEndOfList" data-index="@(skip + take)"></div>
我真的不知道为什么,但是错误已经神奇消失了,我想的太久了,对不起。但是正如Stijn所说,这不会跳过查询,而只会跳过内存中的列表,因此回到平方。
答案 0 :(得分:1)
如果您要使用跳过并仅从数据库中加载部分通知,请使用...
DbSet<ApplicationUserNotification>()
.Where(n => n.ApplicationUserId == User.Identity.GetUserId())
.Skip(() => skip)
.Take(() => take)
.ToList()
如果您想知道为什么用.Skip(()=> skip)而不是.Skip(skip),请尝试两种方法,然后看看使用SQL Profiler或其他查询监视工具生成的SQL。您会看到.Skip(()=> skip)会导致参数化查询,而.Skip(skip).Take(take)将烘烤skip的值并进入查询文本,这将减少对SQL的点击计划缓存,导致分页时性能变差。