Как добавить несколько аргументов к лямбда в C# - PullRequest
0 голосов
/ 25 мая 2020

В настоящее время я работаю над проектом по управлению библиотекой. Он имеет 3 таблицы: TblUser, TblBook и TBlBookStatus. Когда пользователь резервирует книгу, идентификатор пользователя из TblUser, идентификатор книги из TblBook сохраняется в другой таблице (TblBookStatus). Я присоединяюсь и создаю новый список в своих таблицах базы данных на c3. Они хранятся в виде списков в моем коде C#. Приведенный ниже код создает список, в котором отображаются зарезервированные книги.

Примечание. Я не подключал bookID и userID в качестве внешнего ключа в TblBookStatus из-за некоторых c причин проекта

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using LibMan.Models.DB;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Data.SqlClient;
using Microsoft.EntityFrameworkCore;

namespace LibMan.Pages
{
    public class LibraryModel : PageModel
    {
        private readonly LibMan.Models.DB.LibManContext _context;
        public string Message { get; set; }
        public LibraryModel(LibMan.Models.DB.LibManContext context)
        {
            _context = context;
            DisplayBook = new List<TblBook>();
;        }
        public IList<TblBookStatus> TblBookStatus { get; set; }
        public IList<TblBook> TblBook { get; set; }
        public IEnumerable<TblBook> DisplayBook { get; set; }
        public IList<TblUser> TblUser{ get; set; }

        public async Task OnGetAsync()
        {
            TblBookStatus = await _context.TblBookStatus.ToListAsync();
            TblBook = await _context.TblBook.ToListAsync();
            TblUser = await _context.TblUser.ToListAsync();

            if (TblBookStatus != null && TblBook != null){
                DisplayBook = TblBook.Where(t => TblBookStatus.Any(ts => ts.BookId == t.BookId));            
            }
        }
    }
}

В строке DisplayBook = TblBook.Where(t => TblBookStatus.Any(ts => ts.BookId == t.BookId)); Я показываю зарезервированную книгу по bookid, а не по пользователю. Я хочу отображать зарезервированные книги текущего авторизованного пользователя, а не всех пользователей зарезервированных книг. Итак, есть ли какой-либо способ реализовать это в лямбда-выражении выше? Я представляю себе что-то подобное, но мой синтаксис неверен.

DisplayBook = TblBook.Where(t => TblBookStatus.Any(ts => ts.BookId == t.BookId),a=> TblUser.Any(as=> as.UserId == a.UserId);

Спасибо за помощь!

Ответы [ 3 ]

2 голосов
/ 25 мая 2020

{РЕДАКТИРОВАТЬ - Ответ был отмечен как правильный, поскольку поведение было предоставлено, но технически не отвечало на вопрос}

Чтобы ответить на вопрос: «Как добавить несколько аргументов в лямбда-выражение в C# ", важно понимать, что в этом случае лямбда-выражение преобразуется в тип делегата, определенный как параметр для методов linq, таких как Where() и Any(). Следовательно, лямда должна соответствовать «сигнатуре» типа делегата, которая определяет его параметры и возвращаемое значение. В большинстве случаев методы linq ожидают делегата с именем Predicate, определенным как delegate bool Predicate<in T>(T obj). Таким образом, преобразованная лямбда должна получить один параметр типа T, являющийся типом элемента Enumerable, и вернуть одно логическое значение.

Таким образом, вы не можете добавлять аргументы в лямбда выражение, которое необходимо преобразовать в делегатов, именно тип делегата определяет параметры и тип возвращаемого значения. Лямбда с "несколькими аргументами" может выглядеть так, в соответствии с подписью делегата divide, два int вход, один double выход:

Func<int, int, double> divide = (x, y) => { return x / y; };

Чтобы обеспечить запрошенное поведение, альтернативный подход, который вы можете рассмотреть:

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

var DisplayBook =  (from book in TblBook
                    from bookStatus in TblBookStatus
                    from user in TblUser
                    where (book.BookId == bookStatus.BookId) && (user.UserId == currentReader) && (user.UserId == bookStatus.ReservedBy)
                    select book).FirstOrDefault();
2 голосов
/ 25 мая 2020

Почему бы просто не присоединить наборы данных по UserId?

DisplayBook = (from book in TblBook
               join stat in TblBookStatus
               on book.BookId equals stat.BookId
               join usr in TblUser
               on stat.UserId equals usr.UserId
               where usr.UserId = <currentUserId>
               Select book).ToList();
1 голос
/ 25 мая 2020

Попробуйте следующее:

//assumuning current userid is in below variable.
int CurrentUserId;// Fetch it from Session object if you store userid on login

DisplayBook = TblBook.Where(t => TblBookStatus.Any(ts => ts.BookId == t.BookId)
              && TblUser.Any(tb=>tb.UserId==CurrentUserId && tb.BookId==t.BookId)); 
...