C# PostgreSQL 1:1表关联查询触发0xc0000005访问违例求助
解决1:1关联导致的Access Violation错误
问题根源
你遇到的0xc0000005访问违例,核心原因是实体类里的导航属性被默认实例化了。比如NotificationDb里的SendStatus = new SendStatusDb(),还有SendStatusDb里的Notification = new NotificationDb()——EF Core加载实体时,两个对象会互相引用并不断创建新实例,形成无限循环,最终触发内存访问错误。
修复步骤
1. 移除导航属性的默认实例化
把实体类里导航属性的= new XXX()初始化代码去掉,让它们默认值为null(适配可空引用类型规则):
[Table("notification")] public class NotificationDb { [Key] public int NotificationId { get; set; } public string Sender { get; set; } = string.Empty; public string Recipient { get; set; } = string.Empty; public string Subject { get; set; } = string.Empty; public string Message { get; set; } = string.Empty; public string Platform { get; set; } = string.Empty; public string SendDate { get; set; } = string.Empty; // 移除默认实例化,保留virtual用于延迟加载 public virtual SendStatusDb? SendStatus { get; set; } } [Table("sendStatus")] public class SendStatusDb { [Key] public int SendId { get; set; } public int Status { get; set; } public string StatusMessage { get; set; } = string.Empty; public int NotificationId { get; set; } // 移除默认实例化,用null!消除非空警告(因为1:1关联中该属性必存在) public virtual NotificationDb Notification { get; set; } = null!; }
2. 按需加载关联数据(可选)
如果需要查询时同时获取SendStatus的关联数据,在查询中使用Include方法,避免延迟加载产生的额外数据库请求:
public List<NotificationModel> GetAllNotifications() { List<NotificationModel> response = new List<NotificationModel>(); // 用Include显式加载关联的SendStatus数据 var data = _mailContext.Notification.Include(n => n.SendStatus).ToList(); data.ForEach(notificationData => { response.Add(new NotificationModel { NotificationId = notificationData.NotificationId, Sender = notificationData.Sender, Recipient = notificationData.Recipient, SendDate = notificationData.SendDate, Message = notificationData.Message, Platform = notificationData.Platform, // 若需要返回状态信息,可添加以下字段 // Status = notificationData.SendStatus?.Status, // StatusMessage = notificationData.SendStatus?.StatusMessage }); }); return response; }
3. 保留现有DbContext关联配置
你在OnModelCreating中配置的1:1关联逻辑是正确的,无需修改:
modelBuilder.Entity<SendStatusDb>(entity => { entity.HasOne(e => e.Notification) .WithOne(e => e.SendStatus) .HasForeignKey<SendStatusDb>(e => e.NotificationId); });
修复原理
EF Core的导航属性设计是由框架负责实例化和数据填充的,手动默认实例化会打破这个机制,导致循环引用引发的无限递归对象创建,最终耗尽内存或触发内存访问违例。移除默认实例化后,EF会根据关联关系正确加载数据,不会出现循环创建的问题。
内容的提问来源于stack exchange,提问作者Razielruss
相关产品推荐
相关产品推荐

