c# - Entity Framework 6.4 + PostgreSQL 关系一对一单边不包括实体
问题描述
我有这个代码和关系:
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,名称,...
地址-> 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 不会将相关对象作为查询的一部分返回。您必须明确指定要作为查询的一部分返回的相关对象。
在下面您可以找到示例代码,以便在查询 User 对象时还可以获取 Address 详细信息(您创建查询的地方,您必须有一个ApplicationContext
类的实例,我假设变量的名称是dbContext):
dbContext.User.Include(u => u.Address).ToList();
上面的代码使用来自 Linq 扩展的ToList()方法。如果您使用Microsoft.EntityFrameworkCore包,您还可以编写上述代码的异步版本,如下所示:
dbContext.User.Include(u => u.Address).ToListAsync();
编辑: 对您的问题进行了 2 个新的编辑,我也在编辑我的答案。
首先,如下更新您的OnModelCreating方法,基本上,我们删除HasForeignKey方法(因为您已经使用类上的属性定义了这种关系),并明确指定WithOne方法与Address实体的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);
推荐阅读
- pytorch - 这是一个正确的 memedice 函数实现吗?更高的值是否意味着更好的分割质量?
- nightwatch.js - Nightwatch First Test 在 `before` 钩子完成之前运行
- python - 尝试使用循环简化我的代码,但我不确定如何在循环中插入迭代器
- java - Spring boot - 多个数据源无法配置数据源url
- python - ModuleNotFoundError:没有名为“django_plotly_dash”的模块
- reactjs - 如何使用数组作为 React 钩子的依赖项
- node.js - TypeScript Ghostscript 导入更改为 gs_
- html - 引导日期选择器不显示日期选项
- azure - 数据从 Azure 传输到 Snowflake 时使用什么加密?
- c - 使用 strsep 的分段错误