Entity Framework如何查询外键值并更新Connections表对应数据行
解决方案
问题根因
你现在遇到的无法直接访问外键的问题,是因为EF Core为一对多关系自动生成了阴影属性作为外键,该属性没有在实体类中显式声明,所以不能直接用b.UserName访问。另外你当前代码还存在变量名混淆的问题:定义的查询结果变量是result,但判断非空用的是result1,会导致逻辑错误。
方案1:直接访问阴影外键实现查询(无需修改实体类)
EF Core提供了EF.Property方法用于访问阴影属性,默认自动生成的外键阴影属性名和User的主键名一致,为UserName,修改代码如下即可实现需求:
if (user == null) { user = new User { UserName = name, Connections = new List<Connection>() }; db.Users.Add(user); } // 通过EF.Property访问阴影外键查询对应连接 var existingConn = db.Connections .SingleOrDefault(c => EF.Property<string>(c, "UserName") == name); if (existingConn != null) { // 存在则更新记录 existingConn.ConnectionID = Context.ConnectionId; existingConn.UserAgent = Context.GetHttpContext()?.Request.Headers["User-Agent"].ToString(); existingConn.Connected = true; } else { // 不存在则新增记录 user.Connections.Add(new Connection { ConnectionID = Context.ConnectionId, UserAgent = Context.GetHttpContext()?.Request.Headers["User-Agent"].ToString(), Connected = true }); } db.SaveChanges();
方案2:正确配置显式外键,避免阴影属性报错
你之前直接加UserName属性报错大概率是配置冲突/缺失,按照以下步骤配置即可正常使用显式外键:
- 修改Connection实体类,补全外键、导航属性和主键声明:
public class Connection { // 显式设置ConnectionID为主键(EF要求实体必须有主键,缺失也会导致运行错误) [Key] [Required] public string? ConnectionID { get; set; } [Required] public string? UserAgent { get; set; } [Required] public bool Connected { get; set; } // 显式声明外键 [Required] public string? UserName { get; set; } // 关联User的导航属性 public User? User { get; set; } }
- 若仍有冲突,在
UserContext的OnModelCreating方法中显式配置关系:
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Connection>() .HasOne<User>(c => c.User) .WithMany(u => u.Connections) .HasForeignKey(c => c.UserName) .IsRequired(); }
配置完成后你就可以直接用db.Connections.SingleOrDefault(b => b.UserName == name)查询,不会再报阴影状态错误。
内容的提问来源于stack exchange,提问作者uk3ndt
相关产品推荐
相关产品推荐

