如何在 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();
我目前正在从事一个图书馆管理项目。它有 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();