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

时间:2019-05-19 14:50:16

标签: entity-framework entity-framework-core ef-fluent-api

我通过 Fluent API 实体框架中创建了一个映射,但是在定义应忽略子属性时,抛出以下异常:

  

System.ArgumentException:'表达式'x =>   x.PaisCompleto.Descricao'不是有效的属性表达式。的   表达式应该表示一个简单的属性访问:'t =>   t.MyProperty'。'

Mapeamento

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
    }    
}

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; }
}

1 个答案:

答案 0 :(得分:0)

实体中的关系应仅反映实体,而不应反映DTO或非实体类。如果您确实希望在实体中引用非实体类,则应将整个非实体引用标记为NotMapped

EF确实支持继承,但除非有必要,否则我将避免继承。 AFAIK基于您可以使用的表结构,EF Core中的支持仍然受到一定限制。

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表。

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

当您加载Endereco并想通过DTO获得关联的查找值(代码+描述)时,请使用CidadeCompleto代码查找适当的DTO,并在视图模型中填充需要代码和描述的视图。实体应反映数据库中的数据。视图模型和DTO反映了您希望视图/消费者看到的内容。希望将这两个问题分开放置,而不是将特定于视图的字段和结构与数据表示形式混合在一起。