如何高效获取LINQ查询中存在或新建记录的ID?
优化你的LINQ查询:高效获取存在或新增记录的ID
嘿,我来帮你梳理下这个问题哈!首先得提个小细节:你原代码里有个冗余操作——var sys = db.Systems.Add(new Systems() {...})已经把新实体添加到上下文了,后面再调用db.Systems.Add(sys)属于重复操作,会增加不必要的上下文跟踪,记得把这行删掉哦。
回到你的核心需求:不管记录存在与否,都要高效拿到对应的ID。其实完全不用维护两个独立变量,这里有几种简洁又高效的实现方式:
方式一:用单一变量统一接收结果(直观易懂)
这种方式逻辑清晰,适合大多数场景,用一个变量存储最终的实体,最后直接取ID即可:
int systemId; var targetSys = db.Systems.FirstOrDefault(s => s.Name == name && s.OrganizationID == 4); if (targetSys == null) { targetSys = new Systems() { Name = name, OrganizationID = 4, Online = true, SerialNumber = "1zz34343" }; db.Systems.Add(targetSys); db.SaveChanges(); } systemId = targetSys.ID; // 后续直接使用systemId就行
方式二:用空合并运算符简化代码(紧凑简洁)
如果创建实体的逻辑不复杂,可以用??空合并运算符把判断和创建合并,让代码更紧凑:
var targetSys = db.Systems.FirstOrDefault(s => s.Name == name && s.OrganizationID == 4) ?? db.Systems.Add(new Systems() { Name = name, OrganizationID = 4, Online = true, SerialNumber = "1zz34343" }).Entity; // 只有新增实体时才需要保存更改 if (db.Entry(targetSys).State == EntityState.Added) { db.SaveChanges(); } var systemId = targetSys.ID;
新增的实体在SaveChanges后,主键ID会被自动填充,所以直接取targetSys.ID就好。
方式三:封装成复用方法(适合多处调用)
如果这个“获取或创建”的逻辑在项目里多次用到,把它封装成方法能大幅提升代码复用性:
public int GetOrCreateSystemId(YourDbContext db, string name) { var targetSys = db.Systems.FirstOrDefault(s => s.Name == name && s.OrganizationID == 4); if (targetSys == null) { targetSys = new Systems() { Name = name, OrganizationID = 4, Online = true, SerialNumber = "1zz34343" }; db.Systems.Add(targetSys); db.SaveChanges(); } return targetSys.ID; }
调用时直接写var systemId = GetOrCreateSystemId(db, name);就行,后续要修改逻辑也只需改这一处。
额外性能优化提示
如果这个查询的调用频率很高,建议给Systems表的Name和OrganizationID字段创建复合索引,这会让FirstOrDefault的查询速度大幅提升,比代码层面的优化效果更显著哦。
内容的提问来源于stack exchange,提问作者Nate Pet
相关产品推荐
相关产品推荐

