c# - EF Core - 更新实体
问题描述
我想通过实体框架核心产品实体更新数据库。
在每次加载一个产品时,我想增加一个访问次数。
产品上下文类:
[Table("product")]
public class Product
{
[Key]
[Column("id", TypeName = "int")]
public int Id { get; set; }
[Column("name")]
public string Name { get; set; }
[Column("active", TypeName = "bit")]
public bool Active { get; set; }
[Column("visited")]
public int Visited { get; set; }
// last group
[Column("group_id")]
public int GroupId { get; set; }
[ForeignKey("GroupId")]
public virtual Group Group { get; set; }
// first group
[Column("top_group_id")]
public int? TopGroupId { get; set; }
[ForeignKey("TopGroupId")]
public virtual Group TopGroup { get; set; }
// PN image
[Column("file_image_id")]
public int? ImageId { get; set; }
[ForeignKey("ImageId")]
public virtual File Image { get; set; }
public virtual IEnumerable<ProductGrade> ProductGrades { get; set; }
public virtual IEnumerable<ProductDescription> ProductDescriptions { get; set; }
public virtual IEnumerable<ProductFile> ProductFiles { get; set; }
}
在 Controller 中,我调用 CTOR _context:
// In class
private readonly ProductContext _context;
// In method
var product = await _context.Products
.OrderBy(b => b.Name)
.Where(w => w.Name == model.Name)
.Select(c => new ProductResDto
{
Id = c.Id,
PartNumber = c.Name,
Group = c.Group.FullLink,
GroupId = c.GroupId,
Type = c.TopGroup.Name,
Image = new FileDto
{
Name = c.Image.Name,
GroupName = c.Image.FileGroup.Name,
Url = (c.Group.Top.Link != "/" ? c.Group.Top.Link : c.Group.Link) + "/pn/" + c.Image.Url,
Title = c.Image.Title,
Type = c.Image.FileType.MineType
}
}).FirstAsync();
ProductResDto 类:
public class ProductResDto
{
[JsonIgnore] public int Id { get; set; }
public string PartNumber { get; set; }
public string Type { get; set; }
public string Group { get; set; }
[JsonIgnore] public int GroupId { get; set; }
public ICollection<ParameterValueDto> Parameters { get; set; }
public ICollection<ProductValueDto> Descriptions { get; set; }
public ICollection<ProductValueDto> Grades { get; set; }
public ICollection<FileGroupDto> Files { get; set; }
public FileDto Image { get; set; }
public ICollection<BreadCrumbDto> BreadCrumbs { get; set; }
public RelatedProductResDto RelatedProducts { get; set; }
}
我想简单地更新产品记录,例如:
var data = await _context.Products
.OrderBy(b => b.Name)
.Where(w => w.Name == model.Name && w.Active).FirstAsync();
var product = new ProductResDto
{
Id = data.Id,
PartNumber = data.Name,
Group = data.Group.FullLink,
GroupId = data.GroupId,
Type = data.TopGroup.Name,
Image = new FileDto
{
Name = data.Image.Name,
GroupName = data.Image.FileGroup.Name,
Url = (data.Group.Top.Link != "/" ? data.Group.Top.Link : data.Group.Link) + "/pn/" + data.Image.Url,
Title = data.Image.Title,
Type = data.Image.FileType.MineType
}
};
data.Visited += 1;
_context.Products.Update(data);
await _context.SaveChangesAsync();
我只得到错误,因为变量数据只有原始数据 pro DB Product。有没有更好的方法可以更轻松地做到这一点?
就像在控制器中我将数据库上下文类产品及其所有依赖项分配给 ProductResDto 一样?
错误:
System.NullReferenceException:“对象引用未设置为对象的实例。”
var product = new ProductResDto
在行中
它仅加载产品但没有引用,这是我要求的简单方法,例如在我使用的控制器中var product = await _context.Products
感谢您的任何帮助
解决方案
您需要添加.Include()
语句,因为没有它们,EF Core 将不会加载相关的属性Group
,TopGroup
并且Image
(这称为延迟加载)并且正如您在图像中看到的那样,这些属性确实为空。
看起来您也在使用更深层次的嵌套属性,您可以使用.ThenInclude()
.
方法如下:
var data = await _context.Products
.Include(p => p.Group).ThenInclude(g => g.Top)
.Include(p => p.TopGroup)
.Include(p => p.Image).ThenInclude(i => i.FileGroup)
.Include(p => p.Image).ThenInclude(i => i.FileType)
.OrderBy(b => b.Name)
.Where(w => w.Name == model.Name && w.Active)
.FirstAsync();
此示例可能尚未 100% 完成,在这种情况下,您需要添加更多.Include
和/或.ThenInclude
语句。
EF Core 始终分析完整的 LINQ 查询语句。由于.Select()
第一个代码块中的语句中存在的内容,EF Core 会看到您需要嵌套属性,并且它将创建也加载这些属性的 SQL。但是如果没有.Select()
给 EF Core 这个信息,那么你需要添加.Include()
语句 + 可能还有.ThenInclude()
语句。
推荐阅读
- reactjs - 在 react-admin 中保存后 CheckboxGroupInput 不呈现
- c# - 如何在 WPF 中实现等效的拆分视图容器?
- python - Windows Defender 阻止我的愚蠢程序
- javascript - ng-model 在值更改时不更新
- javascript - 使用 Material-ui 库反应渲染问题
- listview - ScrollController animateTo 方法在 NotifcationListener 的 onNotification 方法期间不会触发
- wpf - 如何在listview wpf VB.net中实现延迟加载
- mysql - 类型错误:无法读取未定义的属性“文件名”--multer
- python - Django - 如何单独编辑和提交多个表单然后呈现回同一页面?
- python - 将文本文件拆分为较小的文件