Entity Framework Core 6新增实体被自动分离问题求助
EF Core 6自动分离新建的ParkStatistics实体,部分统计数据未写入数据库
我正在用Entity Framework Core 6开发对接车牌识别摄像头的项目,功能是加载车牌数据存入停放车辆表和统计表,用于后续违规检测。目前车辆数据能正常写入,但部分统计数据没成功写入。查看EF日志发现,EF因缺少停车场(ParkingLot)或摄像头(Camera)引用分离了统计实体(ParkStatistics),但调试时这两个对象都存在,且已关联到统计实体上,也没有抛出任何错误。
相关代码如下:
List<Cars> cars = new List<Cars>(); foreach (Camera cam in _parkingLot.Cameras) { ICamera cameraObject = ICamera.GetCameraObjekt(cam); //Loading all license plates from the camera List<Cars> tempCars = cameraObject.GetCars(); cars.AddRange(tempCars); } //Adds new cars to current context _context.AddRange(cars); foreach (Cars car in cars) { //Saving some additional information //since i do not look immediately for //potential violations and want to make //sure that i do not apply rules retroactively ParkTimes parkTimes = GetParkTimes(car); ParkTimes rentTimes = GetRentTimes(car); if (parkTimes != null) { car.ParkStartTime = parkTimes.StartTime; car.ParkEndTime = parkTimes.EndTime; } if (rentTimes != null) { car.RentStartTime = rentTimes.StartTime; car.RentEndTime = rentTimes.EndTime; } //Here's where i save my statistics ParkStatistics stats = new ParkStatistics(); stats.Direction = Convert.ToInt32(car.Direction); stats.Car = car; stats.Timestamp = car.Timestamp; //The camera is attached to the car after creating the car object //after i downloaded the data from the camera. This one is allegedly missing. stats.Camera = car.Camera; stats.CameraName = car.Camera.Name; //We're in a class here and the _parkingLot property is //a global property. This one is also allegedly missing. stats.ParkingLot = _parkingLot; stats.HasRentingService = _parkingLot.HasRentingService; stats.HasParkingMeter = _parkingLot.HasParkingMeter; stats.MaxParkingDuration = _parkingLot.MaxParkingDuration; if (parkTimes != null) { stats.ParkStartTime = parkTimes.StartTime; stats.ParkEndTime = parkTimes.EndTime; } if (rentTimes != null) { stats.RentStartTime = rentTimes.StartTime; stats.RentEndTime = rentTimes.EndTime; } //When i add the statistics object to the context, //the object gets detached. I do not get an exception //here. I only realized that the object is missing //after looking at the database and reading //the EF logs. _context.Add(stats); } _parkingLot.LastUpdate = DateTime.Now; _context.SaveChanges();
问题原因
EF Core添加实体时,如果关联的导航属性对应的实体处于**Detached(分离)**状态,EF会自动将当前实体标记为Detached——因为它无法确定如何处理未被跟踪的关联实体,且默认不会抛出异常。
你的场景里,_parkingLot或car.Camera大概率未被当前上下文跟踪:
_parkingLot如果是外部传入或之前被移出上下文,EF不会跟踪它;car.Camera是在cameraObject.GetCars()中关联到Car对象的,这个Camera实例可能也未被当前上下文跟踪。
解决方案
方案1:确保关联实体被上下文跟踪
在添加ParkStatistics前,将关联的Camera和ParkingLot附加到上下文,强制EF跟踪它们:
// 创建stats后添加这段代码 if (_context.Entry(stats.Camera).State == EntityState.Detached) { _context.Attach(stats.Camera); } if (_context.Entry(stats.ParkingLot).State == EntityState.Detached) { _context.Attach(stats.ParkingLot); } _context.Add(stats);
方案2:直接关联主键而非整个对象
如果不需要修改Camera或ParkingLot,直接设置它们的主键字段(假设主键为Id),这样EF无需跟踪整个对象,性能更优:
// 替换原有的stats.Camera和stats.ParkingLot赋值 stats.CameraId = car.Camera.Id; stats.ParkingLotId = _parkingLot.Id; // 保留CameraName等字段赋值 stats.CameraName = car.Camera.Name;
方案3:开启必填外键验证
对ParkStatistics的外键字段添加[Required]注解,这样SaveChanges时会抛出验证异常,能快速定位问题:
public class ParkStatistics { // ...其他字段 [Required] public int CameraId { get; set; } [Required] public int ParkingLotId { get; set; } // ...导航属性 }
额外建议
- 开启EF Core详细日志,查看实体状态变化的完整流程,确认哪些实体被分离;
- 尽量避免在上下文外创建关联实体后直接传入,优先通过上下文获取或附加实体。
内容的提问来源于stack exchange,提问作者AlphaNERD
相关产品推荐
相关产品推荐

