Entity Framework 6.4 + PostgreSQL关系一对一单边不包含实体

Entity Framework 6.4 + PostgreSQL Relationship One-to-One Unilateral don't include entity

我有这个代码和关系:

namespace Tequila.Models.DTOs
{
    public class ApplicationContext : DbContext
    {
        public ApplicationContext(DbContextOptions options) : base(options)
        {

        }

        public DbSet<Address> Address { get; set; }
        public DbSet<User> User { get; set; }
    }

    [Table("address")]
    public class Address
    {
        [Column("id")]
        public long AddressId { get; set; }

        [Column("user_id")]
        [ForeignKey("User")]
        public long UserId { get; set; }
        public User User { get; set; }
    }

    [Table("user")]
    public class User
    {
        [Key, Column("id")]
        public long UserId { get; set; }

        public Address Address { get; set; }
    }
} 

用户 -> id, name,...

地址 -> id, 地址, user_id...

当我执行此路由以查找用户和您的地址时,SQL 生成的是:

SELECT u.id, u.name, ... , u.password
  FROM user AS u
  WHERE u.id = @__Id_0
  LIMIT 1

我已经通过官方文档和社区尝试了许多其他想法,但我没有成功。

我不明白这个问题是怎么回事。

编辑

我像这样在我的存储库中调用包含在上下文中

User user = context.User.Include("Address").FirstOrDefault(u => u.Id == Id);

User user = context.User.Include("Address").Where(u => u.Id == Id).FirstOrDefault();

然后我创建 OnModelCreating 函数

protected override void OnModelCreating(ModelBuilder builder)
{
    builder.Entity<User>()
            .HasOne(e => e.Address)
            .WithOne()
            .HasForeignKey("Address");
}

我尝试了很多其他配置此功能,但我仍然没有成功。

编辑 2

我使用这个结构来做这个急切加载的查询。我也尝试使用急切加载进行另一个查询,但使用其他实体进行查询,但我遇到了同样的问题。

地址在用户中不是强制性的,但在我的例子中,用户必须在地址中。所以,我想打电话给一个用户,而那个用户就在那个地址上。

仅通过属性设置关系(外键)不足以获取查询的相关数据。出于性能原因,作为默认行为,EF 不会将 return 相关对象作为查询的一部分。您必须明确指定要 return 作为查询的一部分的相关对象。

您可以在下面找到示例代码,以便在查询 User 对象时也可以获取 Address 详细信息(您创建查询的地方,您必须有 ApplicationContext class 的实例,我假设变量的名称是 dbContext):

dbContext.User.Include(u => u.Address).ToList();

上面的代码使用 Linq 扩展中的 ToList() 方法。如果你使用 Microsoft.EntityFrameworkCore 包,你还可以编写上面代码的异步版本,如下所示:

dbContext.User.Include(u => u.Address).ToListAsync();

编辑: 对您的问题进行了 2 次新编辑,我也在编辑我的答案。

首先,更新你的 OnModelCreating 方法如下,基本上,我们删除 HasForeignKey 方法(因为你已经使用属性定义了这种关系在你的 class) 上并且还明确指定 WithOne 方法与 User 属性 具有一对一关系地址实体(在Microsoft Docs 如果您不传递参数,您会发现它的行为方式,很快它会说 如果要使用导航 属性,则必须指定它。):

protected override void OnModelCreating(ModelBuilder builder)
{
    builder.Entity<User>()
        .HasOne(u => u.Address)
        .WithOne(a => a.User);
}

其次,您的查询部分如下:

var user = context.User.Include(u => u.Address).FirstOrDefault(u => u.Id == Id);