首页 > 解决方案 > 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 列中的值

标签: c#domain-driven-designef-core-2.0

解决方案


您不能直接映射相关实体的属性,但您可以通过使用私有属性/字段来解决污染模型的问题。

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调用中保存到数据库中。


推荐阅读