c# - EFCore 2 Fluent API 构建自定义映射规则
问题描述
我有一种情况,我正在尝试构建一个与数据库不完全匹配的域模型,并且我很难弄清楚如何使用 EFCore 构建映射规则
预约领域模型
public class Appointment
{
public string Title { get; set; }
public long UserId { get; set; }
public string UserFullName { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public void MyBusinessLogic(){}
}
这是精简版,但要点是我不希望完整的 User 对象作为我的 Appointment 模型中的属性,例如:
public User User {get;set;} <== trying to avoid adding this to the class
我只想要 UserId 和一些次要元数据,例如用户的全名。
我已经为 EFCore 映射设置了一个配置,以仍然构建和映射 FK 关系,如下所示
internal class AppointmentConfiguration : IEntityTypeConfiguration<Appointment>
{
public void Configure(EntityTypeBuilder<Appointment> builder)
{
builder.Property(x => x.Title)
.IsRequired(true)
.HasMaxLength(AppointmentConst.MaxTitleLength);
builder.Property(x => x.Description)
.IsRequired(true)
.HasMaxLength(AppointmentConst.MaxDescriptionLength);
builder.HasOne<User>()
.WithMany()
.HasForeignKey(x => x.UserId)
.OnDelete(DeleteBehavior.Restrict);
}
}
所以我想弄清楚的是,是否可以为 UserFullName 属性构建某种映射规则,通过连接 First 和 Last name 列从 User 表中读取它的数据,但不应该写入该表。
几乎就像使用 Automapper 之类的工具一样。
基本上,我只想对 EFCore 说,当我查询 Appointment 数据时,从 User 表中获取 UserFullName 的值并连接 FirstName 和 LastName 列中的值
解决方案
您不能直接映射相关实体的属性,但您可以通过使用私有属性/字段来解决污染模型的问题。
public class Appointment
{
...
private User user;
public string UserFullName => $"{user.FirstName} {user.LastName}";
...
}
builder.HasOne<User>("user")
.WithMany()
.HasForeignKey(x => x.UserId)
.OnDelete(DeleteBehavior.Restrict);
并且不要忘记.Include("user")
在构建查询时。
另请注意,您的 DbContext 现在正在跟踪此用户,如果您对其进行修改,它的更改将在以后的SaveChanges
调用中保存到数据库中。
推荐阅读
- javascript - 从 JavaScript 响应中填充数组
- c++ - 在 macOS arm64 架构上使用 x86 库和 OpenMP
- rest - 如何在 RestAssured 中获取响应值
- javascript - 映射函数内的javascript中的array.push不会影响块外声明的数组
- python - 字典列表到新列中
- c - 堆排序打印出 0 而不是假定的数组元素
- events - R包deSolve:使用函数和数据框的组合触发不同的事件
- javascript - Revolut Checkout 集成 - 找不到沙盒上的 embed.js
- vagrant - 尝试使用 Docker Swarm 将工作人员添加到管理器但收到“Swarm:错误”
- reactjs - React.js 成功登录后渲染 App.js