Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Att inkludera en DbSet av en typ i kontexten innebär att den ingår i EF Cores modell. Vi refererar vanligtvis till en sådan typ som en entitet. EF Core kan läsa och skriva entitetsinstanser från/till databasen, och om du använder en relationsdatabas kan EF Core skapa tabeller för dina entiteter via migreringar.
Inkludera typer i modellen
Enligt konventionen inkluderas typer som exponeras i DbSet-egenskaper i din kontext i modellen som entiteter. Entitetstyper som anges i OnModelCreating metoden ingår också, liksom alla typer som hittas genom att rekursivt utforska navigeringsegenskaperna för andra identifierade entitetstyper.
I kodexemplet nedan ingår alla typer:
-
Blogingår eftersom den exponeras i en DbSet-egenskap i kontexten. -
Postingår eftersom den identifieras via navigeringsegenskapenBlog.Posts. -
AuditEntryeftersom den anges iOnModelCreating.
internal class MyContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<AuditEntry>();
}
}
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; }
public Blog Blog { get; set; }
}
public class AuditEntry
{
public int AuditEntryId { get; set; }
public string Username { get; set; }
public string Action { get; set; }
}
Exkludera typer från modellen
Om du inte vill att en typ ska ingå i modellen kan du exkludera den:
[NotMapped]
public class BlogMetadata
{
public DateTime LoadedFromDatabase { get; set; }
}
Exkludering från migreringar
Det är ibland användbart att ha samma entitetstyp mappad i flera DbContext typer. Detta gäller särskilt när du använder avgränsade kontexter, för vilka det är vanligt att ha en annan DbContext typ för varje begränsad kontext.
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<IdentityUser>()
.ToTable("AspNetUsers", t => t.ExcludeFromMigrations());
}
Med den här konfigurationsmigreringen skapas AspNetUsers inte tabellen, men IdentityUser ingår fortfarande i modellen och kan användas normalt.
Om du behöver börja hantera tabellen med hjälp av migreringar igen bör en ny migrering skapas där AspNetUsers inte exkluderas. Nästa migrering kommer nu att innehålla alla ändringar som gjorts i tabellen.
Tabellnamn
Enligt konventionen konfigureras varje entitetstyp för mappning till en databastabell med samma namn som dbSet-egenskapen som exponerar entiteten. Om det inte finns någon DbSet för den angivna entiteten används klassnamnet.
Du kan konfigurera tabellnamnet manuellt:
[Table("blogs")]
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
}
Tabellschema
När du använder en relationsdatabas skapas tabeller enligt konventionen i databasens standardschema. Till exempel använder dbo Microsoft SQL Server schemat (SQLite stöder inte scheman).
Du kan konfigurera tabeller som ska skapas i ett specifikt schema enligt följande:
[Table("blogs", Schema = "blogging")]
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
}
I stället för att ange schemat för varje tabell kan du också definiera standardschemat på modellnivå med api:et fluent:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.HasDefaultSchema("blogging");
}
Observera att inställningen av standardschemat även påverkar andra databasobjekt, till exempel sekvenser.
Visa karta
Entitetstyper kan mappas till databasvyer med hjälp av Fluent API.
Anmärkning
EF förutsätter att den refererade vyn redan finns i databasen, att den inte skapas automatiskt i en migrering.
modelBuilder.Entity<Blog>()
.ToView("blogsView", schema: "blogging");
Mappning till en vy tar bort standardtabellmappningen, men entitetstypen kan också mappas till en tabell explicit. I det här fallet används vymappningen för frågor och tabellmappningen används för uppdateringar.
Tips/Råd
Om du vill testa nyckellösa entitetstyper som mappats till vyer med hjälp av den minnesinterna providern mappar du dem till en fråga via ToInMemoryQuery. Mer information finns i dokumentationen för den minnesinterna leverantören.
Tabellvärdefunktionskartläggning
Det går att mappa en entitetstyp till en tabellvärdesfunktion (TVF) i stället för en tabell i databasen. För att illustrera detta ska vi definiera en annan entitet som representerar en blogg med flera inlägg. I exemplet är entiteten nyckellös, men den behöver inte vara det.
public class BlogWithMultiplePosts
{
public string Url { get; set; }
public int PostCount { get; set; }
}
Skapa sedan följande tabellvärdesfunktion i databasen, som endast returnerar bloggar med flera inlägg samt antalet inlägg som är associerade med var och en av dessa bloggar:
CREATE FUNCTION dbo.BlogsWithMultiplePosts()
RETURNS TABLE
AS
RETURN
(
SELECT b.Url, COUNT(p.BlogId) AS PostCount
FROM Blogs AS b
JOIN Posts AS p ON b.BlogId = p.BlogId
GROUP BY b.BlogId, b.Url
HAVING COUNT(p.BlogId) > 1
)
Nu kan entiteten BlogWithMultiplePosts mappas till den här funktionen på följande sätt:
modelBuilder.Entity<BlogWithMultiplePosts>().HasNoKey().ToFunction("BlogsWithMultiplePosts");
Anmärkning
För att mappa en entitet till en tabellvärdesfunktion måste funktionen vara parameterlös.
Normalt mappas entitetsegenskaperna till matchande kolumner som returneras av TVF. Om kolumnerna som returneras av TVF har andra namn än entitetsegenskapen kan entitetens kolumner konfigureras med hjälp av HasColumnName metoden, precis som vid mappning till en vanlig tabell.
När entitetstypen mappas till en tabellvärdesfunktion, frågan:
var query = from b in context.Set<BlogWithMultiplePosts>()
where b.PostCount > 3
select new { b.Url, b.PostCount };
Genererar följande SQL:
SELECT [b].[Url], [b].[PostCount]
FROM [dbo].[BlogsWithMultiplePosts]() AS [b]
WHERE [b].[PostCount] > 3
Tabellkommentar
Du kan ange en godtycklig textkommentar som anges i databastabellen så att du kan dokumentera schemat i databasen:
[Comment("Blogs managed on the website")]
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
}
Entitetstyper av delad typ
Entitetstyper som använder samma CLR-typ kallas för entitetstyper av delad typ. Dessa entitetstyper måste konfigureras med ett unikt namn, som måste anges när entitetstypen av delad typ används, utöver CLR-typen. Det innebär att motsvarande DbSet egenskap måste implementeras med hjälp av ett Set anrop.
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");
});
}
}