Лучший способ .skip () во внешнем списке в Entity Framework - PullRequest
0 голосов
/ 06 декабря 2018

У меня есть 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);
}
* 1006.

Какой лучший способ решить эту проблему без изменения кода для прямого запроса из таблицы пользовательских уведомлений?Фактическое использование этого кода использует класс пользователя, поэтому было бы лучше, если бы я мог получить доступ к уведомлениям пользователя через объект пользователя.

Странно, я ожидал, что по этому поводу возникнет много вопросов, ноПохоже, поисковики пропускают слово «пропустить», поэтому я ничего не могу найти по этому поводу.

====================

Обновление для Мик, я использую его в виде, и у меня есть статический объект, где я могу получить доступ к объекту пользователя под названием «Текущий»:

@{
    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>

Я действительно не знаю, почему, но ошибка волшебным образом исчезлаЯ слишком долго кодировал, думаю, извините.Но, как сказал Стейн, это не пропустит запрос, а только список в памяти, так что вернемся к исходной точке.

1 Ответ

0 голосов
/ 06 декабря 2018

Если вы хотите использовать skip и take, чтобы загрузить только часть уведомлений из базы данных, используйте ...

DbSet<ApplicationUserNotification>()
    .Where(n => n.ApplicationUserId == User.Identity.GetUserId())
    .Skip(() => skip)
    .Take(() => take)
    .ToList()

Если вам интересно, почему .Skip (() => skip)вместо .Skip (пропустить) попробуйте оба и посмотрите на SQL, сгенерированный с использованием SQL Profiler или другого инструмента мониторинга запросов.Вы увидите, что .Skip (() => skip) приводит к параметризованному запросу, тогда как .Skip (skip) .Take (take) запечет значения для skip и примет в текст запроса, что уменьшит попадания в SQLкэш плана, что приводит к снижению производительности при подкачке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...