{"id":44396,"date":"2023-02-21T10:00:00","date_gmt":"2023-02-21T18:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/dotnet\/?p=44396"},"modified":"2023-02-27T10:24:06","modified_gmt":"2023-02-27T18:24:06","slug":"announcing-ef8-preview-1","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/dotnet\/announcing-ef8-preview-1\/","title":{"rendered":"EF Core 8 Preview 1: Raw, lazy, and on-time"},"content":{"rendered":"<p>The first preview of Entity Framework Core (EF Core) 8 is <a href=\"https:\/\/www.nuget.org\/packages\/Microsoft.EntityFrameworkCore\/8.0.0-preview.1.23111.4\">available on NuGet today<\/a>!<\/p>\n<h2>Basic information<\/h2>\n<p>EF Core 8, or just EF8, is the successor to EF Core 7, and is scheduled for release in November 2023, at the same time as .NET 8.<\/p>\n<p>EF8 currently targets .NET 6. This will likely be updated to .NET 8 as we near release.<\/p>\n<p>EF8 will align with .NET 8 as a long-term support (LTS) release. See the <a href=\"https:\/\/dotnet.microsoft.com\/platform\/support\/policy\/dotnet-core\">.NET support policy<\/a> for more information.<\/p>\n<h2>EF8 themes<\/h2>\n<p>Before looking at the new features in preview 1, let&#8217;s take a quick look at the plan for large investments in data access for .NET 8. These investments are covered by five themes:<\/p>\n<h3>Highly requested features<\/h3>\n<ul>\n<li><a href=\"https:\/\/learn.microsoft.com\/ef\/core\/what-is-new\/ef-core-8.0\/plan#json-columns\">JSON columns<\/a>\nBuild on EF7 JSON support to further power the document\/relational hybrid pattern.<\/li>\n<li><a href=\"https:\/\/learn.microsoft.com\/ef\/core\/what-is-new\/ef-core-8.0\/plan#value-objects\">Value objects<\/a>\nApplications can use DDD-style value objects in EF models.<\/li>\n<li><a href=\"https:\/\/learn.microsoft.com\/ef\/core\/what-is-new\/ef-core-8.0\/plan#sql-queries-for-unmapped-types\">SQL queries for unmapped types<\/a>\nApplications can execute more types of SQL query without dropping down to ADO.NET or using third-party libraries.<\/li>\n<\/ul>\n<h3>Cloud native and devices<\/h3>\n<ul>\n<li><a href=\"https:\/\/learn.microsoft.com\/ef\/core\/what-is-new\/ef-core-8.0\/plan#aot-and-trimming-with-ef-core\">AOT and trimming with EF Core<\/a>\nSmall, fast-starting EF Core applications with no dynamic code generation.<\/li>\n<li><a href=\"https:\/\/learn.microsoft.com\/ef\/core\/what-is-new\/ef-core-8.0\/plan#aot-and-trimming-for-adonet\">AOT and trimming for ADO.NET<\/a>\nLow-level data access can be used in cloud native applications.<\/li>\n<\/ul>\n<h3>Performance<\/h3>\n<ul>\n<li><a href=\"https:\/\/learn.microsoft.com\/ef\/core\/what-is-new\/ef-core-8.0\/plan#woodstar\">Woodstar<\/a>\nFast, fully managed access to SQL Server and Azure SQL for .NET applications.<\/li>\n<\/ul>\n<h3>Visual Tooling<\/h3>\n<ul>\n<li><a href=\"https:\/\/learn.microsoft.com\/ef\/core\/what-is-new\/ef-core-8.0\/plan#first-class-t4-templates-in-visual-studio\">First-class T4 templates in Visual Studio<\/a>\nLeverage T4 templating across multiple areas in Visual Studio.<\/li>\n<li><a href=\"https:\/\/learn.microsoft.com\/ef\/core\/what-is-new\/ef-core-8.0\/plan#ef-core-database-first-in-visual-studio\">EF Core Database First in Visual Studio<\/a>\nOut-of-the-box Database First tooling in Visual Studio.<\/li>\n<\/ul>\n<h3>Developer experience<\/h3>\n<ul>\n<li><a href=\"https:\/\/learn.microsoft.com\/ef\/core\/what-is-new\/ef-core-8.0\/plan#theme-developer-experience\">Make EF Core better<\/a>\nImprove the developer experience be making many small improvements to EF Core<\/li>\n<\/ul>\n<h3>Find out more and give feedback<\/h3>\n<p>Your feedback on planning is important. Please comment on <a href=\"https:\/\/github.com\/dotnet\/efcore\/issues\/29853\">GitHub Issue #29853<\/a> with any feedback or general suggestions about the plan. The best way to indicate the importance of an issue is to vote (\ud83d\udc4d) for that <a href=\"https:\/\/github.com\/dotnet\/efcore\/issues\">issue on GitHub<\/a>. This data will then feed into the <a href=\"core\/what-is-new\/release-planning\">planning process<\/a> for the next release.<\/p>\n<h2>New in EF8 preview 1<\/h2>\n<p>The following sections give an overview of three particular enhancements available in EF8 preview 1: Raw SQL queries for unmapped types, lazy-loading for no-tracking queries, and <code>DateOnly<\/code>\/<code>TimeOnly<\/code> support for SQL Server\/Azure SQL. In total, EF8 preview 1 ships with <a href=\"https:\/\/github.com\/dotnet\/efcore\/issues?q=is%3Aissue+milestone%3A8.0.0-preview1+is%3Aclosed\">more than 60 improvements, both bug fixes and enhancements<\/a>.<\/p>\n<blockquote>\n<p><strong>TIP<\/strong>\nFull details of all new EF8 features can be found in the <a href=\"https:\/\/learn.microsoft.com\/ef\/core\/what-is-new\/ef-core-8.0\/whatsnew\">What&#8217;s New in EF8<\/a> documentation. All the code is available in <a href=\"https:\/\/github.com\/dotnet\/EntityFramework.Docs\">runnable samples on GitHub<\/a>.<\/p>\n<\/blockquote>\n<h3>Raw SQL queries for unmapped types<\/h3>\n<p>EF7 introduced <a href=\"https:\/\/learn.microsoft.com\/ef\/core\/querying\/sql-queries#querying-scalar-non-entity-types\">raw SQL queries returning scalar types<\/a>. This is enhanced in EF8 to include raw SQL queries returning any mappable CLR type, without including that type in the EF model.<\/p>\n<blockquote>\n<p><strong>TIP<\/strong>\nThe code shown here comes from <a href=\"https:\/\/github.com\/dotnet\/EntityFramework.Docs\/tree\/main\/samples\/core\/Miscellaneous\/NewInEFCore8\/RawSqlSample.cs\">RawSqlSample.cs<\/a>.<\/p>\n<\/blockquote>\n<p>Queries using unmapped types are executed using <a href=\"https:\/\/learn.microsoft.com\/dotnet\/api\/microsoft.entityframeworkcore.relationaldatabasefacadeextensions.sqlquery\">SqlQuery<\/a> or <a href=\"https:\/\/learn.microsoft.com\/dotnet\/api\/microsoft.entityframeworkcore.relationaldatabasefacadeextensions.sqlqueryraw\">SqlQueryRaw<\/a>. The former uses string interpolation to parameterize the query, which helps ensure that all non-constant values are parameterized. For example, consider the following database table:<\/p>\n<pre><code class=\"language-sql\">CREATE TABLE [Posts] (\r\n    [Id] int NOT NULL IDENTITY,\r\n    [Title] nvarchar(max) NOT NULL,\r\n    [Content] nvarchar(max) NOT NULL,\r\n    [PublishedOn] date NOT NULL,\r\n    [BlogId] int NOT NULL,\r\n);<\/code><\/pre>\n<p><code>SqlQuery<\/code> can be used to query this table and return instances of a <code>BlogPost<\/code> type with properties corresponding to the columns in the table:<\/p>\n<p>For example:<\/p>\n<pre><code class=\"language-csharp\">public class BlogPost\r\n{\r\n    public int Id { get; set; }\r\n    public string Title { get; set; }\r\n    public string Content { get; set; }\r\n    public DateOnly PublishedOn { get; set; }\r\n    public int BlogId { get; set; }\r\n}<\/code><\/pre>\n<p>For example:<\/p>\n<pre><code class=\"language-csharp\">var start = new DateOnly(2022, 1, 1);\r\nvar end = new DateOnly(2023, 1, 1);\r\nvar postsIn2022 =\r\n    await context.Database\r\n        .SqlQuery&lt;BlogPost&gt;($\"SELECT * FROM Posts as p WHERE p.PublishedOn &gt;= {start} AND p.PublishedOn &lt; {end}\")\r\n        .ToListAsync();<\/code><\/pre>\n<p>When using SQL Server, this query is parameterized and executed as:<\/p>\n<pre><code class=\"language-sql\">SELECT * FROM Posts as p WHERE p.PublishedOn &gt;= @p0 AND p.PublishedOn &lt; @p1<\/code><\/pre>\n<p>The type used for query results can contain common mapping constructs supported by EF Core, such as parameterized constructors and mapping attributes. For example:<\/p>\n<pre><code class=\"language-csharp\">public class BlogPost\r\n{\r\n    public BlogPost(string blogTitle, string content, DateOnly publishedOn)\r\n    {\r\n        BlogTitle = blogTitle;\r\n        Content = content;\r\n        PublishedOn = publishedOn;\r\n    }\r\n\r\n    public int Id { get; private set; }\r\n\r\n    [Column(\"Title\")]\r\n    public string BlogTitle { get; set; }\r\n\r\n    public string Content { get; set; }\r\n    public DateOnly PublishedOn { get; set; }\r\n    public int BlogId { get; set; }\r\n}<\/code><\/pre>\n<blockquote>\n<p><strong>NOTE<\/strong>\nTypes used in this way do not have keys defined and cannot have relationships to other types. Types with relationships must be mapped in the model.<\/p>\n<\/blockquote>\n<p>One nice feature of <code>SqlQuery<\/code> is that it returns an <code>IQueryable<\/code> which can be composed on using LINQ. For example, a &#8216;Where&#8217; clause can be added to the query above:<\/p>\n<pre><code class=\"language-csharp\">var summariesIn2022 =\r\n    await context.Database.SqlQuery&lt;PostSummary&gt;(\r\n            @$\"SELECT b.Name AS BlogName, p.Title AS PostTitle, p.PublishedOn\r\n               FROM Posts AS p\r\n               INNER JOIN Blogs AS b ON p.BlogId = b.Id\")\r\n        .Where(p =&gt; p.PublishedOn &gt;= cutoffDate &amp;&amp; p.PublishedOn &lt; end)\r\n        .ToListAsync();<\/code><\/pre>\n<p>This is executed as:<\/p>\n<pre><code class=\"language-sql\">SELECT [n].[BlogName], [n].[PostTitle], [n].[PublishedOn]\r\nFROM (\r\n         SELECT b.Name AS BlogName, p.Title AS PostTitle, p.PublishedOn\r\n         FROM Posts AS p\r\n                  INNER JOIN Blogs AS b ON p.BlogId = b.Id\r\n     ) AS [n]\r\nWHERE [n].[PublishedOn] &gt;= @__cutoffDate_1 AND [n].[PublishedOn] &lt; @__end_2<\/code><\/pre>\n<p>At this point it is worth remembering that all of the above can be done completely in LINQ without the need to write any SQL. This includes returning instances of an unmapped type like <code>PostSummary<\/code>. For example, the preceding query can be written in LINQ as:<\/p>\n<pre><code class=\"language-csharp\">var summariesByLinq =\r\n    await context.Posts.Select(\r\n            p =&gt; new PostSummary\r\n            {\r\n                BlogName = p.Blog.Name,\r\n                PostTitle = p.Title,\r\n                PublishedOn = p.PublishedOn,\r\n            })\r\n        .Where(p =&gt; p.PublishedOn &gt;= start &amp;&amp; p.PublishedOn &lt; end)\r\n        .ToListAsync();<\/code><\/pre>\n<p>Which translates to much cleaner SQL:<\/p>\n<pre><code class=\"language-sql\">SELECT [b].[Name] AS [BlogName], [p].[Title] AS [PostTitle], [p].[PublishedOn]\r\nFROM [Posts] AS [p]\r\nINNER JOIN [Blogs] AS [b] ON [p].[BlogId] = [b].[Id]\r\nWHERE [p].[PublishedOn] &gt;= @__start_0 AND [p].[PublishedOn] &lt; @__end_1<\/code><\/pre>\n<blockquote>\n<p><strong>TIP<\/strong>\nEF is able to generate cleaner SQL when it is responsible for the entire query than it is when composing over user-supplied SQL because, in the former case, the full semantics of the query are available to EF.<\/p>\n<\/blockquote>\n<p>So far, all the queries have been executed directly against tables. <code>SqlQuery<\/code> can also be used to return results from a view without mapping the view type in the EF model. For example:<\/p>\n<pre><code class=\"language-csharp\">var summariesFromView =\r\n    await context.Database.SqlQuery&lt;PostSummary&gt;(\r\n            @$\"SELECT * FROM PostAndBlogSummariesView\")\r\n        .Where(p =&gt; p.PublishedOn &gt;= cutoffDate &amp;&amp; p.PublishedOn &lt; end)\r\n        .ToListAsync();<\/code><\/pre>\n<p>Likewise, <code>SqlQuery<\/code> can be used for the results of a function:<\/p>\n<pre><code class=\"language-csharp\">var summariesFromFunc =\r\n    await context.Database.SqlQuery&lt;PostSummary&gt;(\r\n            @$\"SELECT * FROM GetPostsPublishedAfter({cutoffDate})\")\r\n        .Where(p =&gt; p.PublishedOn &lt; end)\r\n        .ToListAsync();<\/code><\/pre>\n<p>The returned <code>IQueryable<\/code> can be composed upon when it is the result of a view or function, just like it can be for the result of a table query. Stored procedures can be also be executed using <code>SqlQuery<\/code>, but most databases do not support further composition. For example:<\/p>\n<pre><code class=\"language-csharp\">var summariesFromStoredProc =\r\n    await context.Database.SqlQuery&lt;PostSummary&gt;(\r\n            @$\"exec GetRecentPostSummariesProc\")\r\n        .ToListAsync();<\/code><\/pre>\n<h3>Lazy-loading for no-tracking queries<\/h3>\n<p>EF8 adds support for <a href=\"https:\/\/learn.microsoft.com\/ef\/core\/querying\/related-data\/lazy\">lazy-loading of navigations<\/a> on entities that are not being tracked by the <code>DbContext<\/code>. This means a no-tracking query can be followed by lazy-loading of navigations on the entities returned by the no-tracking query.<\/p>\n<blockquote>\n<p><strong>TIP<\/strong>\nThe code for the lazy-loading examples shown below comes from <a href=\"https:\/\/github.com\/dotnet\/EntityFramework.Docs\/tree\/main\/samples\/core\/Miscellaneous\/NewInEFCore8\/LazyLoadingSample.cs\">LazyLoadingSample.cs<\/a>.<\/p>\n<\/blockquote>\n<p>For example, consider a no-tracking query for blogs:<\/p>\n<pre><code class=\"language-csharp\">var blogs = await context.Blogs.AsNoTracking().ToListAsync();<\/code><\/pre>\n<p>If <code>Blog.Posts<\/code> is configured for lazy-loading, for example, using lazy-loading proxies, then accessing <code>Posts<\/code> will cause it to load from the database:<\/p>\n<pre><code class=\"language-csharp\">Console.WriteLine();\r\nConsole.Write(\"Choose a blog: \");\r\nif (int.TryParse(ReadLine(), out var blogId))\r\n{\r\n    Console.WriteLine(\"Posts:\");\r\n    foreach (var post in blogs[blogId - 1].Posts)\r\n    {\r\n        Console.WriteLine($\"  {post.Title}\");\r\n    }\r\n}<\/code><\/pre>\n<p>EF8 also reports whether or not a given navigation is loaded for entities not tracked by the context. For example:<\/p>\n<pre><code class=\"language-csharp\">foreach (var blog in blogs)\r\n{\r\n    if (context.Entry(blog).Collection(e =&gt; e.Posts).IsLoaded)\r\n    {\r\n        Console.WriteLine($\" Posts for blog '{blog.Name}' are loaded.\");\r\n    }\r\n}<\/code><\/pre>\n<p>There are a few important considerations when using lazy-loading in this way:<\/p>\n<ul>\n<li>Lazy-loading will only succeed until the <code>DbContext<\/code> used to query the entity is disposed.<\/li>\n<li>Entities queried in this way a reference to their <code>DbContext<\/code>, even though they are not tracked by it. Care should be taken to avoid memory leaks if the entity instances will have long lifetimes.<\/li>\n<li>Explicitly detaching the entity by setting its state to <code>EntityState.Detached<\/code> severs the reference to the <code>DbContext<\/code> and lazy-loading will no longer work.<\/li>\n<li>Remember that all lazy-loading uses synchronous I\/O, since there is no way to access a property in an asynchronous manner.<\/li>\n<\/ul>\n<p>Lazy-loading from untracked entities works for both <a href=\"https:\/\/learn.microsoft.com\/ef\/core\/querying\/related-data\/lazy#lazy-loading-with-proxies\">lazy-loading proxies<\/a> and <a href=\"https:\/\/learn.microsoft.com\/ef\/core\/querying\/related-data\/lazy#lazy-loading-without-proxies\">lazy-loading without proxies<\/a>.<\/p>\n<h3>DateOnly\/TimeOnly supported on SQL Server<\/h3>\n<p>The <a href=\"https:\/\/learn.microsoft.com\/dotnet\/api\/system.dateonly\">System.DateOnly<\/a> and <a href=\"https:\/\/learn.microsoft.com\/dotnet\/api\/system.timeonly\">System.TimeOnly<\/a> types were introduced in .NET 6 and have been supported for several database providers (e.g. SQLite, MySQL, and PostgreSQL) since their introduction. For SQL Server, the recent release of a <a href=\"https:\/\/www.nuget.org\/packages\/Microsoft.Data.SqlClient\/\">Microsoft.Data.SqlClient<\/a> package targeting .NET 6 has allowed <a href=\"https:\/\/github.com\/dotnet\/SqlClient\/pull\/1813\">ErikEJ to add support for these types at the ADO.NET level<\/a>. This in turn paved the way for support in EF8 for <code>DateOnly<\/code> and <code>TimeOnly<\/code> as properties in entity types.<\/p>\n<blockquote>\n<p><strong>TIP<\/strong>\n<code>DateOnly<\/code> and <code>TimeOnly<\/code> can be used in EF Core 6 and 7 using the <a href=\"https:\/\/www.nuget.org\/packages\/ErikEJ.EntityFrameworkCore.SqlServer.DateOnlyTimeOnly\">ErikEJ.EntityFrameworkCore.SqlServer.DateOnlyTimeOnly<\/a> community package from <a href=\"https:\/\/github.com\/ErikEJ\">@ErikEJ<\/a>.<\/p>\n<\/blockquote>\n<p>For example, consider the following EF model for British schools:<\/p>\n<pre><code class=\"language-csharp\">public class School\r\n{\r\n    public int Id { get; set; }\r\n    public string Name { get; set; } = null!;\r\n    public DateOnly Founded { get; set; }\r\n    public List&lt;Term&gt; Terms { get; } = new();\r\n    public List&lt;OpeningHours&gt; OpeningHours { get; } = new();\r\n}\r\n\r\npublic class Term\r\n{\r\n    public int Id { get; set; }\r\n    public string Name { get; set; } = null!;\r\n    public DateOnly FirstDay { get; set; }\r\n    public DateOnly LastDay { get; set; }\r\n    public School School { get; set; } = null!;\r\n}\r\n\r\n[Owned]\r\npublic class OpeningHours\r\n{\r\n    public OpeningHours(DayOfWeek dayOfWeek, TimeOnly? opensAt, TimeOnly? closesAt)\r\n    {\r\n        DayOfWeek = dayOfWeek;\r\n        OpensAt = opensAt;\r\n        ClosesAt = closesAt;\r\n    }\r\n\r\n    public DayOfWeek DayOfWeek { get; private set; }\r\n    public TimeOnly? OpensAt { get; set; }\r\n    public TimeOnly? ClosesAt { get; set; }\r\n}<\/code><\/pre>\n<blockquote>\n<p><strong>TIP<\/strong>\nThe code shown here comes from <a href=\"https:\/\/github.com\/dotnet\/EntityFramework.Docs\/tree\/main\/samples\/core\/Miscellaneous\/NewInEFCore8\/DateOnlyTimeOnlySample.cs\">DateOnlyTimeOnlySample.cs<\/a>.<\/p>\n<p><strong>NOTE<\/strong>\nThis model represents only British schools and stores times as local (GMT) times. Handling different timezones would complicate this code significantly. Note that using <code>DateTimeOffset<\/code> would not help here, since opening and closing times have different offsets depending whether daylight saving time is active or not.<\/p>\n<\/blockquote>\n<p>These entity types map to the following tables when using SQL Server or Azure SQL. Notice that the <code>DateOnly<\/code> properties map to <code>date<\/code> columns, and the <code>TimeOnly<\/code> properties map to <code>time<\/code> columns.<\/p>\n<pre><code class=\"language-sql\">CREATE TABLE [Schools] (\r\n    [Id] int NOT NULL IDENTITY,\r\n    [Name] nvarchar(max) NOT NULL,\r\n    [Founded] date NOT NULL,\r\n    CONSTRAINT [PK_Schools] PRIMARY KEY ([Id]));\r\n\r\nCREATE TABLE [OpeningHours] (\r\n    [SchoolId] int NOT NULL,\r\n    [Id] int NOT NULL IDENTITY,\r\n    [DayOfWeek] int NOT NULL,\r\n    [OpensAt] time NULL,\r\n    [ClosesAt] time NULL,\r\n    CONSTRAINT [PK_OpeningHours] PRIMARY KEY ([SchoolId], [Id]),\r\n    CONSTRAINT [FK_OpeningHours_Schools_SchoolId] FOREIGN KEY ([SchoolId]) REFERENCES [Schools] ([Id]) ON DELETE CASCADE);\r\n\r\nCREATE TABLE [Term] (\r\n    [Id] int NOT NULL IDENTITY,\r\n    [Name] nvarchar(max) NOT NULL,\r\n    [FirstDay] date NOT NULL,\r\n    [LastDay] date NOT NULL,\r\n    [SchoolId] int NOT NULL,\r\n    CONSTRAINT [PK_Term] PRIMARY KEY ([Id]),\r\n    CONSTRAINT [FK_Term_Schools_SchoolId] FOREIGN KEY ([SchoolId]) REFERENCES [Schools] ([Id]) ON DELETE CASCADE);<\/code><\/pre>\n<p>Queries using <code>DateOnly<\/code> and <code>TimeOnly<\/code> work in the expected manner. For example, the following LINQ query finds schools that are currently open:<\/p>\n<pre><code class=\"language-csharp\">openSchools = await context.Schools\r\n    .Where(\r\n        s =&gt; s.Terms.Any(\r\n                 t =&gt; t.FirstDay &lt;= today\r\n                      &amp;&amp; t.LastDay &gt;= today)\r\n             &amp;&amp; s.OpeningHours.Any(\r\n                 o =&gt; o.DayOfWeek == dayOfWeek\r\n                      &amp;&amp; o.OpensAt &lt; time &amp;&amp; o.ClosesAt &gt;= time))\r\n    .ToListAsync();<\/code><\/pre>\n<p>This query translates to the following SQL, as shown by calling <a href=\"https:\/\/learn.microsoft.com\/dotnet\/api\/microsoft.entityframeworkcore.entityframeworkqueryableextensions.toquerystring\">ToQueryString()<\/a> on the IQueryable object:<\/p>\n<pre><code class=\"language-sql\">DECLARE @__today_0 date = '2023-02-07';\r\nDECLARE @__dayOfWeek_1 int = 2;\r\nDECLARE @__time_2 time = '19:53:40.4798052';\r\n\r\nSELECT [s].[Id], [s].[Founded], [s].[Name], [o0].[SchoolId], [o0].[Id], [o0].[ClosesAt], [o0].[DayOfWeek], [o0].[OpensAt]\r\nFROM [Schools] AS [s]\r\nLEFT JOIN [OpeningHours] AS [o0] ON [s].[Id] = [o0].[SchoolId]\r\nWHERE EXISTS (\r\n    SELECT 1\r\n    FROM [Term] AS [t]\r\n    WHERE [s].[Id] = [t].[SchoolId] AND [t].[FirstDay] &lt;= @__today_0 AND [t].[LastDay] &gt;= @__today_0) AND EXISTS (\r\n    SELECT 1\r\n    FROM [OpeningHours] AS [o]\r\n    WHERE [s].[Id] = [o].[SchoolId] AND [o].[DayOfWeek] = @__dayOfWeek_1 AND [o].[OpensAt] &lt; @__time_2 AND [o].[ClosesAt] &gt;= @__time_2)\r\nORDER BY [s].[Id], [o0].[SchoolId]<\/code><\/pre>\n<h2>How to get EF8 preview 1<\/h2>\n<p>EF8 is distributed exclusively as a set of NuGet packages. For example, to add the SQL Server provider to your project, you can use the following command using the dotnet tool:<\/p>\n<pre><code class=\"language-bash\">dotnet add package Microsoft.EntityFrameworkCore.SqlServer --version 8.0.0-preview.1.23111.4<\/code><\/pre>\n<h2>Installing the EF8 Command Line Interface (CLI)<\/h2>\n<p>The <code>dotnet-ef<\/code> tool must be installed before executing EF8 Core migration or scaffolding commands.<\/p>\n<p>To install the tool globally, use:<\/p>\n<pre><code class=\"language-bash\">dotnet tool install --global dotnet-ef --version 8.0.0-preview.1.23111.4<\/code><\/pre>\n<p>If you already have the tool installed, you can upgrade it with the following command:<\/p>\n<pre><code class=\"language-bash\">dotnet tool update --global dotnet-ef --version 8.0.0-preview.1.23111.4<\/code><\/pre>\n<h2>The .NET Data Community Standup<\/h2>\n<p>The .NET data access team is now live streaming every other Wednesday at 10am Pacific Time, 1pm Eastern Time, or 18:00 UTC. Join the stream learn and ask questions about many .NET Data related topics.<\/p>\n<ul>\n<li><a href=\"https:\/\/aka.ms\/efstandups\">Watch our YouTube playlist<\/a> of previous shows<\/li>\n<li><a href=\"https:\/\/live.dot.net\">Visit the .NET Community Standup<\/a> page to preview upcoming shows<\/li>\n<li><a href=\"https:\/\/github.com\/dotnet\/efcore\/issues\/22700\">Submit your ideas<\/a> for a guest, product, demo, or other content to cover<\/li>\n<\/ul>\n<h2>Documentation and Feedback<\/h2>\n<p>The starting point for all EF Core documentation is <a href=\"https:\/\/docs.microsoft.com\/ef\/\">docs.microsoft.com\/ef\/<\/a>. Please file issues found and any other feedback on the <a href=\"https:\/\/github.com\/dotnet\/efcore\">dotnet\/efcore GitHub repo<\/a>.<\/p>\n<h2>Helpful Links<\/h2>\n<p>The following links are provided for easy reference and access.<\/p>\n<ul>\n<li>EF Core Community Standup Playlist: <a href=\"https:\/\/aka.ms\/efstandups\">aka.ms\/efstandups<\/a><\/li>\n<li>Main documentation: <a href=\"https:\/\/aka.ms\/efdocs\">aka.ms\/efdocs<\/a><\/li>\n<li>What&#8217;s New in EF Core 8: <a href=\"https:\/\/aka.ms\/ef7-new\">aka.ms\/ef7-new<\/a><\/li>\n<li>What&#8217;s New in EF Core 7: <a href=\"https:\/\/aka.ms\/ef8-new\">aka.ms\/ef8-new<\/a><\/li>\n<li>Issues and feature requests for EF Core: <a href=\"https:\/\/github.com\/dotnet\/efcore\/issues\">github.com\/dotnet\/efcore\/issues<\/a><\/li>\n<li>Entity Framework Roadmap: <a href=\"https:\/\/aka.ms\/efroadmap\">aka.ms\/efroadmap<\/a><\/li>\n<li>Bi-weekly updates: <a href=\"https:\/\/aka.ms\/ef-news\">aka.ms\/ef-news<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Announcing Entity Framework Core 8 (EF8)Preview 1 with raw SQL queries, lazy-loading, DateOnly\/TimeOnly and more!<\/p>\n","protected":false},"author":13047,"featured_media":44498,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[685,859],"tags":[7701,7250,7705,7694,70],"class_list":["post-44396","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dotnet","category-entity-framework","tag-dotnet-8","tag-ef-core","tag-ef8","tag-efcore","tag-entity-framework"],"acf":[],"blog_post_summary":"<p>Announcing Entity Framework Core 8 (EF8)Preview 1 with raw SQL queries, lazy-loading, DateOnly\/TimeOnly and more!<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/44396","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/users\/13047"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/comments?post=44396"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/44396\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media\/44498"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media?parent=44396"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/categories?post=44396"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/tags?post=44396"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}