如何在 C# 中向 lambda 添加多个参数

How to add multiple arguments to lambda in C#

我目前正在从事一个图书馆管理项目。它有 3 tables,TblUser、TblBook 和 TBlBookStatus。当用户预订一本书时,TblUser 中的 userID,TblBook 中的 bookID 存储在另一个 table(TblBookStatus) 中。我正在加入并在 c3 上的数据库 tables 上创建一个新列表。它们作为列表存储在我的 C# 代码中。下面的代码创建了一个列表,它显示了预订的书籍。

注意:由于某些项目特定原因,我没有将 bookID 和 userID 作为外键连接到 TblBookStatus

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显示预订的书,而不是通过用户显示。 我想显示当前登录用户的预订书籍,而不是所有用户的预订书籍。那么有什么可能的方法可以在上面的 lambda 语句上实现它吗?我正在想象这样的事情,但我的语法错误。

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

感谢您的帮助!

试试这个:

//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)); 

{ 编辑 - 答案被标记为正确,因为提供了行为但没有技术上回答问题}

要回答问题:"How to add multiple arguments to lambda in C#",重要的是要了解在这种情况下,lambda 表达式被转换为委托类型,定义为 linq 方法的参数,例如 Where()Any()。因此,lamda 必须匹配定义其参数和 return 值的委托类型的 "signature"。在大多数情况下,linq 方法需要一个名为 Predicate 的委托,定义为 delegate bool Predicate<in T>(T obj)。因此,转换后的 lambda 必须接收 一个 类型 T 的参数,即 Enumerable 元素类型,并且 return 一个布尔值。

综上所述,您不能向要转换为委托的 lambda 表达式添加参数,委托类型决定参数和 return 类型。一个 "multiple argument" lambda 可能看起来像这样,符合委托 divide 的签名,两个 int in,一个 double out:

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();

为什么不简单地通过 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();