c# - 查询列表中的单个项目
问题描述
问题
我想在我的详细信息页面上显示一只宠物。我无法理解如何编写 LINQ(Method Syntax) 从数据库中提取单个宠物/物品。
到目前为止我的理解
使用 LINQ 时,它的闪亮目的是能够遍历IEnumerable
数据库中的数组或列表。当您查看我HomeController
的 .
要求
使用方法语法,我应该使用什么查询来拉单个宠物?
家庭控制器.cs
[HttpGet("pet/{PetId}")]
public IActionResult Detail(Pet singlePet)
{
List<Pet> Animal = _context.Pets
//***MISSING QUERY CODE HERE***
return View("Pet", singlePet);
}
详细信息.cshtml
@model PetViewModel
<div>
<h1>Pet Shelter</h1>
@foreach (Pet creature in Model.Pets)
{
<h3>Details about: @creature.Name</h3>
<div>
<p>Pet Type: @creature.Type</p>
<p>Description: @creature.Description</p>
<p>Skill One:@creature.Skill1</p>
<p>Skill Two:@creature.Skill2</p>
<p>Skill Three:@creature.Skill3</p>
</div>
}
</div>
PetViewModel.cs
using System.Collections.Generic;
namespace petShelter.Models
{
public class PetViewModel
{
public Pet Animal { get; set; }
public List<Pet> Pets { get; set; }
public List<Owner> Owners { get; set; }
public Owner Owner { get; set; }
}
}
宠物.cs
using System;
using System.ComponentModel.DataAnnotations;
namespace petShelter.Models
{
public class Pet
{
[Key]
public int PetId { get; set; }
[Required]
public string Name { get; set; }
[Required]
public string Type { get; set; }
[Required]
public string Description { get; set; }
public string Skill1 { get; set; }
public string Skill2 { get; set; }
public string Skill3 { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { get; set; }
public Owner Owner { get; set; }
public int? OwnerId { get; set; }
}
}
解决方案
精简版
利用
var singlePet=_context.Pets.Find(someId);
或者
var singlePet=_context.Pets.FirstOrDefault(x=>x.PetId=someId);
解释
LINQ 查询不查询列表。它们由 LINQ 提供程序转换为目标数据存储可以理解的任何内容。查询数据库时,它们被转换为 SQL。
List<Pet> Animal = _context.Pets
不会编译,这是一件非常好的事情——如果编译了,它会将整个表加载到内存中而不是查询它。过滤将在客户端执行,没有索引的好处。由于浪费了 IO、浪费了 RAM,甚至更糟糕的是,当只需要一个行时,对表中的每一行都进行了锁定,因此性能将比简单的 SQL 查询差几个数量级。过多的锁将导致尝试使用同一张表的所有其他请求延迟。
Pets
是一个DbSet<T>
,不是一个List<T>
。它不是一个容器,它代表一个实体,本身不包含任何数据。它可用于编写转换为 SQL 的查询。
假设PetId
是主键Pet
,加载单个记录的最简单和最快的方法是调用DbSet.Find。此方法使用提供的主键值检索对象。
这个查询:
var singlePet=_context.Pets.Find(someId);
翻译成
select ...
from Pets
where PetID=@id
这将在 DbContext 中加载和缓存Pet 实例。之后,每次Find
在同一个请求中调用相同的PK值,都会返回缓存的对象。
查询
var singlePet=_context.Pets.FirstOrDefault(x=>x.PetId=someId);
将翻译为
select top 1 ...
from Pets
where PetID=@id
在这种情况下没有缓存任何内容。
推荐阅读
- javascript - 在 electron-build node-adodb 出现错误后:'Spawn C:\WINDOWS\SysWOW64\cscript.exe 错误'
- bash - 如何将大量备份文件导入 Postgresql 数据库
- android - SwipeRefreshLayout 与 BottomAppbar 重叠
- javascript - 在 node.js 中使用 npm 包 Twitter 发布推文(不工作)
- python - spark-submit 和相关配置的问题
- ios - UniversalLink 中应该传递什么值?
- javascript - Asp.net signalR onclose 仅被调用一次
- mysql - 如何编写用于从用户收藏列表中删除产品项目的 sql 查询
- python - 如何用分类神经网络训练不好的奖励?
- python - 如何将 Pandas 数据框转换为具有列表中值的字典