【问题标题】:How to add multiple arguments to lambda in C#如何在 C# 中向 lambda 添加多个参数
【发布时间】:2020-09-12 07:38:23
【问题描述】:

我目前正在从事图书馆管理项目。它有 3 个表,TblUser、TblBook 和 TBlBookStatus。当用户预订一本书时,来自 TblUser 的用户 ID、来自 TblBook 的 bookID 存储在另一个表(TblBookStatus)中。我正在加入并在 c3 上的数据库表上创建一个新列表。它们在我的 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 =&gt; TblBookStatus.Any(ts =&gt; 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);

感谢您的帮助!

【问题讨论】:

    标签: c# asp.net razor ssms razor-pages


    【解决方案1】:

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

    要回答这个问题:“如何在 C# 中向 lambda 添加多个参数”,重要的是要了解在这种情况下,lambda 表达式被转换为委托类型,定义为 linq 方法的参数,例如如Where()Any()。因此,lamda 必须与定义其参数和返回值的委托类型的“签名”相匹配。在大多数情况下,linq 方法需要一个名为Predicate 的委托,定义为delegate bool Predicate&lt;in T&gt;(T obj)。因此,转换后的 lambda 必须接收 T 类型的 一个 参数,即 Enumerable 元素类型,并返回单个布尔值。

    总而言之,您不能向要转换为委托的 lambda 表达式添加参数,而是委托类型决定了参数和返回类型。 “多参数” lambda 可能看起来像这样,符合委托 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();
    

    【讨论】:

    • 您能否提出一种方法,让我可以将会话中的用户 ID 提取到 currentReader 中?
    • 恐怕我不能从你在这里提供的东西中得到。也许问另一个问题,详细说明您当前如何登录用户:)
    • 嗨,我实际上找到了一种方法并尝试了这个,但页面上没有显示任何内容。如果我提供更多信息,您能帮我解决这个问题吗?
    • 我使用var UserEmail = HttpContext.Session.GetString("Email"); 来获取当前登录的用户电子邮件,并且我确信它不会返回为空,我在控制台上将其打印出来,但是当我使用解决方案时上面提供的,我没有在页面上显示任何内容。
    • 解决了!我删除了DisplayBook前面的var decleration,因为我之前已经声明并初始化了它,它充当局部变量。这不是标题所要求的,但我将其标记为解决方案。谢谢!
    【解决方案2】:

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

    【讨论】:

    • 当我将它粘贴到我的代码上时,我收到一条错误消息:**查询正文必须以 select 子句或 group 子句结尾。 ** 我该如何解决这个问题?我对这些东西真的很陌生,所以感谢您的帮助。
    • 这还需要进一步的工作来过滤CurrentUser
    • where usr.UserId = &lt;currentUserId&gt; 更改为 where usr.UserId == &lt;currentUserId&gt;,这也有效,感谢您的帮助!
    • @Kedar @Fuzzyy 我喜欢这个答案,因为它使用了join。这更像是处理表结构的标准、正确的方法。
    【解决方案3】:

    试试这个:

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

    【讨论】:

    • 我认为最后一个表达式可能不正确,因为如果我理解正确,TblUser 的元素将没有BookId 属性?应该是&amp;&amp; tb.UserId == ts.ReservedBy?@AjayKelkar
    • TblBookBookId 上加入TblBookStatus,在UserId 上加入UserTbl
    • 你是对的@GeorgeKerwood,我在 TblUser 上没有 BookId。
    猜你喜欢
    • 1970-01-01
    • 2020-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-09
    • 1970-01-01
    • 2019-10-17
    • 2014-06-27
    相关资源
    最近更新 更多