Entity Framework API介绍 -- DbSet<>().Find()

本文介绍了Entity Framework的DbSet<>().Find()方法,该方法通过主键高效地查找实体,优先从DbContext缓存中获取,避免不必要的数据库查询。示例展示了如何查找单一主键和联合主键的实体,并指出Find方法能处理新添加但未保存到数据库的实体。

过去我们常常使用Where或First(FirstOrDefault)方法来查找对应的实体,比如:


var query = context.CertInfoMakeDetails.ToList().Where(make => int.Parse(make.CertCode) >= startcode &&
                                                                               int.Parse(make.CertCode) <=
                                                                               (startcode + count - 1) &&
                                                                               make.ProductName == productName);
// Data/ApplicationDbContext.cs using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; using UserManagementSystem.Web.Models; namespace UserManagementSystem.Web.Data { public class ApplicationDbContext : IdentityDbContext<ApplicationUser> { // =================================== // 🔹 自定义业务实体 DbSet // =================================== /// <summary> /// 【人】自然人信息 /// </summary> public DbSet<Person> Persons { get; set; } /// <summary> /// 【照片】人员关联的照片 /// </summary> public DbSet<PersonPhoto> PersonPhotos { get; set; } /// <summary> /// 【单位】例如乡镇、村委等组织机构(你在 RegisterViewModel 中用了 Cmb) /// </summary> public DbSet<Cmb> Cmbs { get; set; } /// <summary> /// 【团队】如工作小组、服务队等 /// </summary> public DbSet<Team> Teams { get; set; } /// <summary> /// 【分组】用于对 Team 进行分类管理(例如:按区域、职能划分) /// </summary> public DbSet<Group> Groups { get; set; } // ✅ 新增:【户】家庭单位 /// <summary> /// 【户】代表一个家庭单位,是人员登记的基础单元 /// </summary> public DbSet<Household> Households { get; set; } // =================================== // 🛠️ 配置关系(OnModelCreating) // =================================== protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); // 必须调用基类,否则 Identity 表会出错 // -------------------------------------------------- // 1. Person - PersonPhoto: 一对多 // -------------------------------------------------- builder.Entity<Person>() .HasMany(p => p.Photos) .WithOne(ph => ph.Person) .HasForeignKey(ph => ph.PersonId) .OnDelete(DeleteBehavior.Cascade); // 删除 Person 时,自动删除所有照片 // -------------------------------------------------- // 2. Cmb 排序索引(你用了 OrderBy(c => c.SortOrder)) // -------------------------------------------------- builder.Entity<Cmb>() .HasIndex(c => c.SortOrder); // -------------------------------------------------- // 3. 可选:为常用查询添加索引 // -------------------------------------------------- builder.Entity<Person>() .HasIndex(p => p.IdCardNumber) .IsUnique() .HasFilter("[IdCardNumber] IS NOT NULL"); // 身份证唯一(允许 null) builder.Entity<Person>() .HasIndex(p => new { p.HouseholdId, p.Name }); // 户内按姓名查快 // -------------------------------------------------- // 4. 设置默认值(EF Core 9 支持) // -------------------------------------------------- builder.Entity<Person>() .Property(p => p.CreatedAt) .HasDefaultValueSql("GETUTCDATE()"); builder.Entity<Person>() .Property(p => p.UpdatedAt) .HasDefaultValueSql("GETUTCDATE()"); // ✅ 新增:为 Household 设置 CreatedAt/UpdatedAt 默认值 builder.Entity<Household>() .Property(h => h.CreatedAt) .HasDefaultValueSql("GETUTCDATE()"); builder.Entity<Household>() .Property(h => h.UpdatedAt) .HasDefaultValueSql("GETUTCDATE()"); // -------------------------------------------------- // 5. Team - Group: 多个 Team 属于一个 Group(可选) // 每个 Team 可以属于一个 Group,也可以不属于任何 Group(GroupId 可为空) // -------------------------------------------------- builder.Entity<Team>() .HasOne<Group>() // Team 拥有一个 Group .WithMany(g => g.Teams) // Group 包含多个 Team .HasForeignKey(t => t.GroupId) // 外键是 Team.GroupId .OnDelete(DeleteBehavior.SetNull); // 删除 Group 后,Team 的 GroupId 设为 null // -------------------------------------------------- // 6. 可以为 Group 和 Team 添加索引提升性能 // -------------------------------------------------- builder.Entity<Group>() .HasIndex(g => g.Name) .IsUnique(); // 组名唯一 builder.Entity<Team>() .HasIndex(t => t.Name); // 团队名称索引 builder.Entity<Team>() .HasIndex(t => t.GroupId); // 外键索引,提高连接查询效率 // ✅ 新增:Household - Team: 可选的一对多关系 builder.Entity<Household>() .HasOne<Team>() // Household 属于一个 Team .WithMany(t => t.Households) // Team 包含多个 Household .HasForeignKey(h => h.TeamId) // 外键字段:Household.TeamId .OnDelete(DeleteBehavior.SetNull); // 删除 Team 后,Household.TeamId 设为 null // ✅ 新增:为 Household.TeamId 添加索引(提升查询性能) builder.Entity<Household>() .HasIndex(h => h.TeamId); // ✅ 新增:Person - Household: 可选的一对多关系 builder.Entity<Person>() .HasOne(p => p.Household) // Person 属于一个 Household(可空) .WithMany(h => h.Members) // Household 有多个成员 .HasForeignKey(p => p.HouseholdId) // 外键字段:Person.HouseholdId .OnDelete(DeleteBehavior.SetNull); // 删除 Household 后,Person.HouseholdId 设为 null // ✅ 新增:HouseholdCode 唯一索引(避免重复编码) builder.Entity<Household>() .HasIndex(h => h.HouseholdCode) .IsUnique() .HasFilter("[HouseholdCode] IS NOT NULL"); } // =================================== // ⚙️ 可选:重写 SaveChanges 以自动更新时间戳 // =================================== public override int SaveChanges() { UpdateTimestamps(); return base.SaveChanges(); } public override int SaveChanges(bool acceptAllChangesOnSuccess) { UpdateTimestamps(); return base.SaveChanges(acceptAllChangesOnSuccess); } public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default) { UpdateTimestamps(); return await base.SaveChangesAsync(cancellationToken); } public override async Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default) { UpdateTimestamps(); return await base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken); } private void UpdateTimestamps() { var entries = ChangeTracker.Entries() .Where(e => (e.Entity is Person || e.Entity is Household) && // ✅ 扩展类型判断 (e.State == EntityState.Added || e.State == EntityState.Modified)); foreach (var entry in entries) { if (entry.State == EntityState.Added) { entry.Property("CreatedAt").CurrentValue = DateTime.UtcNow; } entry.Property("UpdatedAt").CurrentValue = DateTime.UtcNow; } } } } 这是我的Household,请帮我添加软删除
最新发布
10-08
// 控制器完整代码 using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using WebApplication1.Models; using Newtonsoft.Json; using WebApplication1.Scripts; namespace WebApplication1.Controllers { public class JobManagemController : Controller { AoutEntities db = new AoutEntities(); ReturnListJsonData jsonData = new ReturnListJsonData(); public ActionResult Index() { return View(); } #region 模糊查询 public ActionResult GetList(int page, int limit, string name, string code) { var list = db.Job.Where(a => a.IsDel == false).ToList(); if (!string.IsNullOrEmpty(name)) { list = list.Where(a => a.JobName.Contains(name)).ToList(); } if (!string.IsNullOrEmpty(code)) { list = list.Where(a => a.JobCode.Contains(code)).ToList(); } var offset = (page - 1) * limit; var data = list.OrderByDescending(a => a.ModifyDate).Skip(offset).Take(limit); jsonData.code = 0; jsonData.count = list.Count; jsonData.data = data; jsonData.msg = "success"; return Json(jsonData, JsonRequestBehavior.AllowGet); } #endregion #region 添加职位 [HttpPost] public ActionResult AddJob(Job job) { try { job.IsDel = false; job.ModifyDate = DateTime.Now; db.Job.Add(job); db.SaveChanges(); jsonData.code = 0; jsonData.msg = "添加成功"; } catch (Exception ex) { jsonData.code = 1; jsonData.msg = ex.Message; } return Json(jsonData); } #endregion #region 更新职位 [HttpPost] public ActionResult UpdateJob(Job job) { try { var model = db.Job.FirstOrDefault(a => a.ID == job.ID); if (model != null) { model.JobName = job.JobName; model.JobCode = job.JobCode; model.ModifyDate = DateTime.Now; db.SaveChanges(); jsonData.code = 0; jsonData.msg = "更新成功"; } else { jsonData.code = 1; jsonData.msg = "未找到该职位"; } } catch (Exception ex) { jsonData.code = 1; jsonData.msg = ex.Message; } return Json(jsonData); } #endregion #region 删除职位 [HttpPost] public ActionResult DeleteJob(Guid ID) { try { var model = db.Job.FirstOrDefault(a => a.ID == ID); if (model != null) { model.IsDel = true; // 软删除 db.SaveChanges(); jsonData.code = 0; jsonData.msg = "删除成功"; } else { jsonData.code = 1; jsonData.msg = "未找到该职位"; } } catch (Exception ex) { jsonData.code = 1; jsonData.msg = ex.Message; } return Json(jsonData); } #endregion } } <!-- 前端页面完整代码 --> @{ Layout = null; } <!DOCTYPE html> <html> <head> <link href="~/Scripts/layui/css/layui.css" rel="stylesheet" /> <script src="~/Scripts/layui/layui.js"></script> <script src="~/Scripts/jquery-3.4.1.js"></script> <style> body { padding: 10px 20px 20px 20px; width: 90% } .but { margin-top: -5px } </style> </head> <body> <fieldset class="layui-elem-field"> <legend> <span class="layui-breadcrumb"> <a href="">首页</a> <a href="">职位管理</a> </span> </legend> <div class="layui-field-box"> <div class="layui-form-item"> <div class="layui-inline"> <label class="layui-form-label">职位名称</label> <div class="layui-input-block"> <input type="text" name="name" id="name" autocomplete="off" class="layui-input"> </div> </div> <div class="layui-inline"> <label class="layui-form-label">职位代码</label> <div class="layui-input-inline"> <input type="text" name="code" id="code" autocomplete="off" class="layui-input"> </div> </div> <button type="button" class="layui-btn layui-btn-radius but" id="searchButton" onclick="Search()"><i class="layui-icon layui-icon-search"></i>查询</button> <button type="button" class="layui-btn layui-bg-blue but" onclick="AddJob()"><i class="layui-icon layui-icon-addition"></i>添加</button> </div> </div> </fieldset> <fieldset class="layui-elem-field"> <table class="layui-hide" id="test" lay-filter="test"></table> <script type="text/html" id="toolDemo"> <div class="layui-clear-space"> <a class="layui-btn layui-btn-xs" lay-event="edit" id="Edit"><i class="layui-icon layui-icon-edit"></i>编辑</a> <a class="layui-btn layui-btn-xs layui-bg-orange" lay-event="del" id="del"><i class="layui-icon layui-icon-clear"></i>删除</a> </div> </script> </fieldset> <script> var tableIns; layui.use(['table', 'layer', 'form'], function () { var table = layui.table; var layer = layui.layer; // 创建渲染实例 tableIns = table.render({ elem: '#test', url: '/JobManagem/GetList', page: true, cols: [[ { type: 'numbers', width: '15%', title: '序列号' }, { field: 'JobName', width: '20%', title: '职位名称' }, { field: 'JobCode', width: '20%', title: '职位代码' }, { field: 'ModifyDate', width: '20%', title: '修改时间', templet: function (d) { return formatDate(d.ModifyDate); } }, { title: '操作', width: '25%', templet: '#toolDemo' } ]], }); // 编辑删除事件 table.on('tool(test)', function (obj) { var data = obj.data; if (obj.event === 'edit') { EditJob(data); } else if (obj.event === 'del') { DeleteJob(data, obj); } }); }); function formatDate(dateStr) { if (!dateStr) return ''; // 提取时间戳(兼容 "/Date(123456789)/" 格式) var timestamp = parseInt(dateStr.replace(/\/Date$(\d+)$\//, '$ 1')); var date = new Date(timestamp); return date.getFullYear() + '-' + ('0' + (date.getMonth() + 1)).slice(-2) + '-' + // 月份从0开始,需+1 ('0' + date.getDate()).slice(-2); } // 添加职位弹窗 function AddJob() { layer.open({ type: 1, title: ‘添加职位’, content: <div style="padding:20px"> <div class="layui-form-item"> <label class="layui-form-label">职位名称</label> <div class="layui-input-block"> <input type="text" id="add_name" class="layui-input"> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">职位代码</label> <div class="layui-input-block"> <input type="text" id="add_code" class="layui-input"> </div> </div> </div> , btn: [‘保存’, ‘取消’], yes: function (index) { ParseError: KaTeX parse error: Expected '}', got 'EOF' at end of input: … JobName: (‘#add_name’).val(), JobCode: $(‘#add_code’).val() }, function (res) { if (res.code == 0) { layer.close(index); Search(); // 刷新列表 } else { layer.msg(‘操作失败:’ + res.msg); } }); } }); } // 编辑职位弹窗 function EditJob(data) { layer.open({ type: 1, title: '编辑职位', content: ` <div style="padding:20px"> <div class="layui-form-item"> <label class="layui-form-label">职位名称</label> <div class="layui-input-block"> <input type="text" id="edit_name" value="${data.JobName}" class="layui-input"> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">职位代码</label> <div class="layui-input-block"> <input type="text" id="edit_code" value="${data.JobCode}" class="layui-input"> </div> </div> </div> `, btn: ['更新', '取消'], yes: function (index) { $.post('/JobManagem/UpdateJob', { ID: data.ID, JobName: $('#edit_name').val(), JobCode: $('#edit_code').val() }, function (res) { if (res.code == 0) { layer.close(index); Search(); } else { layer.msg('更新失败:' + res.msg); } }); } }); } // 删除职位 function DeleteJob(data, obj) { layer.confirm('真的删除行 [' + data.JobName + '] 么', function (index) { $.post('/JobManagem/DeleteJob', { ID: data.ID }, function (res) { if (res.code == 0) { obj.del(); layer.close(index); } else { layer.msg('删除失败:' + res.msg); } }); }); } // 查询重载 function Search() { var nameVal = $('input[name="name"]').val().trim(); var codeVal = $('input[name="code"]').val().trim(); tableIns.reload({ where: { name: nameVal, code: codeVal }, page: { curr: 1 } // 重置分页 }); } </script> </body> </html> 表名:组织机构表(OrganizationStructure) 字段描述 字段名 数据类型 长度 是否主键 是否外键 是否必填 组织机构表主键 ID uniqueidentifier 16 1 FALSE TRUE 组织机构名称 OrgName varchar 200 0 FALSE TRUE 组织机构代码 OrgCode varchar 200 0 FALSE FALSE 级别 Leve int 4 0 FALSE FALSE 父节点 ParentId uniqueidentifier 16 0 FALSE FALSE 创建时间 CreateDate datetime 8 0 FALSE FALSE 修改时间 ModifyDate datetime 8 0 FALSE FALSE 根据我给的数据写出组织机构模块的前端后端
07-11
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值