Typy entit bez klíčů
Poznámka
Tato funkce byla přidána pod název typů dotazů. Později se přejmenovala na typy entit bez klíčů.
Kromě běžných typů entit může model EF Core obsahovat typy entit bez klíčů, které se dají použít k provádění databázových dotazů na data, která neobsahují klíčové hodnoty.
Definování typů entit bez klíčů
Typy entit bez klíčů lze definovat takto:
[Keyless]
public class BlogPostsCount
{
public string BlogName { get; set; }
public int PostCount { get; set; }
}
Charakteristiky typů entit bez klíčů
Typy entit bez klíčů podporují mnoho stejných funkcí mapování jako běžné typy entit, jako je mapování dědičnosti a vlastnosti navigace. V relačních úložištích můžou nakonfigurovat cílové databázové objekty a sloupce prostřednictvím fluent api metod nebo datových poznámek.
Liší se ale od běžných typů entit v tom, že:
- Nelze definovat klíč.
- Nejsou nikdy sledovány pro změny v DbContext , a proto se nikdy nevkládají, aktualizují nebo odstraní do databáze.
- Konvence nikdy nezjistí.
- Podporují pouze podmnožinu možností mapování navigace, konkrétně:
- Nemusí nikdy fungovat jako hlavní konec relace.
- Nemusí mít navigaci na vlastněné entity.
- Můžou obsahovat pouze referenční vlastnosti navigace odkazující na běžné entity.
- Entity nemohou obsahovat navigační vlastnosti na typy entit bez klíčů.
- Je potřeba nakonfigurovat poznámku
[Keyless]
k datům nebo.HasNoKey()
volání metody. - Je možné namapovat na definující dotaz. Definující dotaz je dotaz deklarovaný v modelu, který funguje jako zdroj dat pro typ entity bez klíče.
- Může mít hierarchii, ale musí být namapovaná jako TPH.
- Rozdělení tabulky nebo dělení entit nelze použít.
Scénáře použití
Mezi hlavní scénáře použití pro typy entit bez klíčů patří:
- Slouží jako návratový typ pro dotazy SQL.
- Mapování na zobrazení databáze, která neobsahují primární klíč
- Mapování na tabulky, které nemají definovaný primární klíč
- Mapování na dotazy definované v modelu
Mapování na databázové objekty
Mapování typu entity bez klíče na objekt databáze se dosahuje pomocí ToTable
rozhraní API nebo ToView
fluentu. Z hlediska EF Core je databázový objekt zadaný v této metodě zobrazení, což znamená, že se považuje za zdroj dotazů jen pro čtení a nemůže být cílem operací aktualizace, vložení nebo odstranění. To ale neznamená, že databázový objekt je skutečně nutný k zobrazení databáze. Může se jednat o tabulku databáze, která bude považována za jen pro čtení. U běžných typů entit EF Core naopak předpokládá, že databázový objekt zadaný v ToTable
metodě může být považován za tabulku, což znamená, že se dá použít jako zdroj dotazu, ale také cílený operacemi aktualizace, odstranění a vložení. Ve skutečnosti můžete zadat název zobrazení ToTable
databáze a všechno by mělo fungovat správně, pokud je zobrazení nakonfigurované tak, aby bylo možné aktualizovat databázi.
Příklad
Následující příklad ukazuje, jak použít typy entit bez klíčů k dotazování zobrazení databáze.
Tip
Ukázku pro tento článek najdete na GitHubu.
Nejprve definujeme jednoduchý model blogů a příspěvků:
public class Blog
{
public int BlogId { get; set; }
public string Name { get; set; }
public string Url { get; set; }
public ICollection<Post> Posts { get; set; }
}
public class Post
{
public int PostId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public int BlogId { get; set; }
}
Dále definujeme jednoduché zobrazení databáze, které nám umožní dotazovat se na počet příspěvků přidružených k jednotlivým blogům:
db.Database.ExecuteSqlRaw(
@"CREATE VIEW View_BlogPostCounts AS
SELECT b.Name, Count(p.PostId) as PostCount
FROM Blogs b
JOIN Posts p on p.BlogId = b.BlogId
GROUP BY b.Name");
Dále definujeme třídu, která bude obsahovat výsledek ze zobrazení databáze:
public class BlogPostsCount
{
public string BlogName { get; set; }
public int PostCount { get; set; }
}
Dále nakonfigurujeme typ entity bez klíčů v OnModelCreating pomocí HasNoKey
rozhraní API.
K konfiguraci mapování pro typ entity bez klíčů používáme rozhraní API fluent konfigurace:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder
.Entity<BlogPostsCount>(
eb =>
{
eb.HasNoKey();
eb.ToView("View_BlogPostCounts");
eb.Property(v => v.BlogName).HasColumnName("Name");
});
}
Dále nakonfigurujemeDbContext
, aby zahrnovala :DbSet<T>
public DbSet<BlogPostsCount> BlogPostCounts { get; set; }
Nakonec můžeme dotazovat zobrazení databáze standardním způsobem:
var postCounts = db.BlogPostCounts.ToList();
foreach (var postCount in postCounts)
{
Console.WriteLine($"{postCount.BlogName} has {postCount.PostCount} posts.");
Console.WriteLine();
}
Tip
Všimněte si, že jsme také definovali vlastnost dotazu na úrovni kontextu (DbSet), která bude fungovat jako kořen pro dotazy proti tomuto typu.
Tip
Pokud chcete otestovat typy entit bez klíčů mapované na zobrazení pomocí zprostředkovatele v paměti, namapujte je na dotaz prostřednictvím ToInMemoryQuery. Další informace najdete v dokumentaci k poskytovateli paměti.