Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
As propriedades de sombra são propriedades que não são definidas em sua classe de entidade .NET, mas são definidas para esse tipo de entidade no modelo EF Core. O valor e o estado dessas propriedades são mantidos puramente no Change Tracker. As propriedades de sombra são úteis quando há dados no banco de dados que não devem ser expostos nos tipos de entidade mapeados.
As propriedades do indexador são propriedades de tipo de entidade, que são apoiadas por um indexador na classe de entidade .NET. Eles podem ser acessados usando o indexador nas instâncias de classe .NET. Ele também permite que você adicione propriedades adicionais ao tipo de entidade sem alterar a classe CLR.
Propriedades implícitas de chave estrangeira
As propriedades de sombra geralmente são usadas para propriedades de chave estrangeira, em que são adicionadas ao modelo por convenção quando nenhuma propriedade de chave estrangeira foi encontrada por convenção ou configurada explicitamente. A relação é representada por propriedades de navegação, mas no banco de dados ela é imposta por uma restrição de chave estrangeira e o valor da coluna de chave estrangeira é armazenado na propriedade de sombra correspondente.
A propriedade será nomeada <navigation property name><principal key property name> (a navegação na entidade dependente, que aponta para a entidade principal, é usada para a nomenclatura). Se o nome da propriedade da chave principal começar com o nome da propriedade de navegação, o nome será apenas <principal key property name>. Se não houver nenhuma propriedade de navegação na entidade dependente, o nome do tipo principal concatenado com o nome da propriedade de chave primária ou alternativa será usado em seu lugar <principal type name><principal key property name>.
Por exemplo, a listagem de código a seguir resultará na introdução de uma BlogId propriedade de sombra à Post entidade:
internal class MyContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; }
}
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
public List<Post> Posts { get; set; }
}
public class Post
{
public int PostId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
// Since there is no CLR property which holds the foreign
// key for this relationship, a shadow property is created.
public Blog Blog { get; set; }
}
Configurando propriedades de sombra
Você pode usar a API fluente para configurar propriedades de sombra. Depois de chamar a sobrecarga de cadeia de caracteres Property<TProperty>(String), você poderá encadear qualquer uma das chamadas de configuração que faria para outras propriedades. No exemplo a seguir, como Blog não tem nenhuma propriedade CLR nomeada LastUpdated, uma propriedade de sombra é criada:
internal class MyContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.Property<DateTime>("LastUpdated");
}
}
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
}
Se o nome fornecido ao Property método corresponder ao nome de uma propriedade existente (uma propriedade de sombra ou uma definida na classe de entidade), o código configurará essa propriedade existente em vez de introduzir uma nova propriedade de sombra.
Acessando propriedades de sombra
Os valores da propriedade Shadow podem ser obtidos e alterados por meio da ChangeTracker API:
context.Entry(myBlog).Property("LastUpdated").CurrentValue = DateTime.Now;
As propriedades de sombra podem ser referenciadas em consultas LINQ por meio do EF.Property método estático:
var blogs = context.Blogs
.OrderBy(b => EF.Property<DateTime>(b, "LastUpdated"));
As propriedades de sombra não podem ser acessadas após uma consulta sem acompanhamento, pois as entidades retornadas não são controladas pelo rastreador de alterações.
Configurando propriedades do indexador
Você pode usar a API fluente para configurar as propriedades do indexador. Depois de chamar o método IndexerProperty, você pode encadear qualquer uma das chamadas de configuração que faria para outras propriedades. No exemplo a seguir, Blog tem um indexador definido e ele será usado para criar uma propriedade do indexador.
internal class MyContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>().IndexerProperty<DateTime>("LastUpdated");
}
}
public class Blog
{
private readonly Dictionary<string, object> _data = new Dictionary<string, object>();
public int BlogId { get; set; }
public object this[string key]
{
get => _data[key];
set => _data[key] = value;
}
}
Se o nome fornecido ao IndexerProperty método corresponder ao nome de uma propriedade de indexador existente, o código configurará essa propriedade existente. Se o tipo de entidade tiver uma propriedade, que é apoiada por uma propriedade na classe de entidade, uma exceção será gerada, pois as propriedades do indexador só devem ser acessadas por meio do indexador.
As propriedades do indexador podem ser referenciadas em consultas LINQ por meio do EF.Property método estático, conforme mostrado acima ou usando a propriedade do indexador CLR.
Tipos de entidade do Property Bag
Tipos de entidade que contêm apenas propriedades do indexador são conhecidos como tipos de entidade de compilação de propriedades. Esses tipos de entidade não têm propriedades de sombra e o EF cria propriedades do indexador. Atualmente, somente Dictionary<string, object> é suportado como um tipo de entidade container de propriedades. Ele deve ser configurado como um tipo de entidade de tipo compartilhado com um nome exclusivo e a propriedade correspondente DbSet deve ser implementada usando uma Set chamada.
internal class MyContext : DbContext
{
public DbSet<Dictionary<string, object>> Blogs => Set<Dictionary<string, object>>("Blog");
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.SharedTypeEntity<Dictionary<string, object>>(
"Blog", bb =>
{
bb.Property<int>("BlogId");
bb.Property<string>("Url");
bb.Property<DateTime>("LastUpdated");
});
}
}
Os tipos de entidade do recipiente de propriedades podem ser usados sempre que um tipo de entidade normal é usado, incluindo como um tipo de entidade de propriedade. No entanto, eles têm certas limitações: