通过 Fluent API 定义 EF 映射中的哪个子属性应该被忽略时,抛出 ArgumentException

When defining which subproperty in EF mapping via Fluent API should be ignored, an ArgumentException is thrown

我通过 Fluent APIEntity Framework 中创建了一个映射,但是当定义一个子-属性 应该被忽略,抛出下面的异常:

System.ArgumentException: 'The expression 'x => x.PaisCompleto.Descricao' is not a valid property expression. The expression should represent a simple property access: 't => t.MyProperty'.'

地图

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>, IDesignTimeDbContextFactory<ApplicationDbContext>
{
    protected override void OnModelCreating(ModelBuilder builder)
    {
        builder.ApplyConfiguration(new EnderecoMap());
    }
}

public class EnderecoMap : IEntityTypeConfiguration<Endereco>
{
    public void Configure(EntityTypeBuilder<Endereco> builder)
    {
        builder
            .OwnsOne(g => g.PaisCompleto, pais => {

                pais
                    .Property(c => c.Codigo)
                    .HasColumnName("PaisCodigo")
                    .HasColumnType("varchar(5)");
            });
        builder.Ignore(x => x.PaisCompleto.Descricao);// throw exception

        builder
            .OwnsOne(g => g.CidadeCompleto, cidade => {

                cidade
                    .Property(c => c.Codigo)
                    .HasColumnName("CidadeCodigo")
                    .HasColumnType("varchar(7)");
            });
        builder.Ignore(x => x.CidadeCompleto.Descricao);// throw exception
    }    
}

Entidades Mapeadas

public abstract class Endereco
{
    public DtoConceito<string> CidadeCompleto { get; set; }
    public string CEP { get; set; }
}

public class DtoConceito<T>
{    
    public T Codigo { get; set; }
    public string Descricao { get; set; }
}

实体中的关系应该只反映实体,而不是 DTO 或 non-entity classes。如果您确实希望在实体中引用 non-entity class,则应将整个 non-entity 引用标记为 NotMapped.

EF 确实支持继承,但除非必要,否则我会避免使用它。据我所知,EF Core 中的支持仍然受到一定程度的限制,具体取决于您可以使用它的 table 结构。

public class Endereco
{
    public virtual Conceito CidadeCompleto { get; set; }
    public string CEP { get; set; }
}

// If Conceito is a table...
public class Conceito
{    
    [Key]
    public string Codigo { get; set; }
    public string Descricao { get; set; }
}

然后映射 Conceito...

    builder
        .OwnsOne(g => g.CidadeCompleto)
        .WithOne()
        .HasForgeignKey("CidadeCodigo"); // Shadow property for the FK Code.

这预计 Endereco 有一个名为 "CidadeCompleto" 的 FK,它指向 CidadeCodigo table。

如果 Endereco 有一个没有支持 table 的 CidadeCompleto 的字符串,或者是没有直接 FK 的单独查找 table 的一部分,您只需要一个特定的 DTO代表该代码和单独加载的描述然后我建议让实体映射那里的列,并在视图模型而不是实体中单独管理 DTO 引用。

当您加载 Endereco 并希望为关联的查找值(代码 + 描述)传递 DTO 时,使用 CidadeCompleto 代码查找适当的 DTO 并将其填充到需要代码的视图的视图模型中& 描述。实体应该反映数据库中的数据。视图模型和 DTO 反映了您希望 view/consumer 看到的内容。希望将这两个问题分开,而不是将 view-specific 字段和结构与数据表示混合。