c# - LINQ Query 加入 2 个不同的表
问题描述
我目前正在从事图书馆管理项目,用户在借书时会更新他们的阅读状态。当我使用 linq 连接表时,除了状态之外的所有其他内容都在那里。这是我的模型: 用户模型(TblUser):
using Microsoft.AspNetCore.SignalR;
using System;
using System.Collections.Generic;
namespace LibMan.Models.DB
{
public partial class TblBookStatus
{
public int ResId { get; set; }
public string UserEmail { get; set; }
public int? BookId { get; set; }
public string Status { get; set; }
public virtual TblBook Book { get; set; }
public virtual TblUser User { get; set; }
}
}
图书模型(TblBook):
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace LibMan.Models.DB
{
public partial class TblBook
{
public int BookId { get; set; }
public string Title { get; set; }
public string Author { get; set; }
public string Translator { get; set; }
public string Publisher { get; set; }
public string Description { get; set; }
public string Category { get; set; }
public byte[] Cover { get; set; }
}
}
图书状态模型(TblBookStatus):
using Microsoft.AspNetCore.SignalR;
using System;
using System.Collections.Generic;
namespace LibMan.Models.DB
{
public partial class TblBookStatus
{
public int ResId { get; set; }
public string UserEmail { get; set; }
public int? BookId { get; set; }
public string Status { get; set; }
public virtual TblBook Book { get; set; }
public virtual TblUser User { get; set; }
}
}
继续下面的代码,您可以看到我使用 linq 查询连接创建了 DisplayBook,但我无法在 html 端显示状态。它说
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.AspNetCore.Razor.Language;
using Microsoft.Data.SqlClient;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Internal;
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 IList<TblBook> DisplayBook { get; set; }
public IList<TblUser> TblUser{ get; set; }
[BindProperty]
public async Task OnGetAsync()
{
TblBookStatus = await _context.TblBookStatus.ToListAsync();
TblBook = await _context.TblBook.ToListAsync();
TblUser = await _context.TblUser.ToListAsync();
var UserEmail = HttpContext.Session.GetString("Email");
if (TblBookStatus != null && TblBook != null)
{
DisplayBook = (from book in TblBook
join stat in TblBookStatus
on book.BookId equals stat.BookId
join usr in TblUser
on stat.UserEmail equals usr.Email
where (usr.Email == UserEmail)
select book).ToList();
}
}
}
}
我怎样才能做到这一点?我可以在将 DisplayBook 分配给 Linq 查询结果的语句中执行此操作吗?做这个的最好方式是什么?谢谢!注意:如果需要,我可以提供 html 代码。
解决方案
无需单独查询每个表,然后加入。让 LINQ 为您完成。
var UserEmail = HttpContext.Session.GetString("Email");
var books = _context.TblBookStatus
.Where(
tbs => (tbs.Book != null && tbs.BookId == tbs.Book.BookId) &&
(tbs.User != null && tbs.UserEmail == tbs.User.Email) &&
tbs.UserEmail == UserEmail)
.Select(tbs => tbs.Book);
因为您在 EF 模型中定义了导航属性(使用虚拟属性),所以将自动为您完成连接。在上面的例子中,我设置了 tbs.BookId == tbs.Book.BookId。如果您在实体类型配置中定义了外键,则不需要这样做。您也可以使用 EF 模型中的属性来定义这些关系。
例子:
[ForeignKey("BookId")]
public virtual TblBook Book { get; set; }
编辑:分解您需要返回的内容:
var books = _context.TblBookStatus
.Where(
tbs => (tbs.Book != null && tbs.BookId == tbs.Book.BookId) &&
(tbs.User != null && tbs.UserEmail == tbs.User.Email) &&
tbs.UserEmail == UserEmail)
.Select(tbs => new {
Status = tbs.Status,
BookName = tbs.Book.Name
});
推荐阅读
- r - 如何将 char 列表转换为 R 中的整数列表?
- php - PHP 8 没有显示 short_open_tag 设置
- reactjs - 自定义挂钩的目的是什么?
- python - Using pytest-mock to mock objects and object methods
- node.js - 使用firebase Auth在服务器端登录但不在客户端
- go - 通过 socks5h 代理获取
- android - 如何在没有 Root 的 Android 11 上安装 HttpCanary 证书
- java - 一段时间后关闭警报对话框
- azure - 发布到市场的 Azure 托管应用程序无法向自定义提供程序发出 POST 请求(由于招摇而被阻止?)
- matlab - 无法识别的函数或变量“dip_filtering”