通过 Fluent API 定义 EF 映射中的哪个子属性应该被忽略时,抛出 ArgumentException
When defining which subproperty in EF mapping via Fluent API should be ignored, an ArgumentException is thrown
我通过 Fluent API 在 Entity 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 字段和结构与数据表示混合。
我通过 Fluent API 在 Entity 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 字段和结构与数据表示混合。