{"id":5967,"date":"2025-11-26T01:21:11","date_gmt":"2025-11-26T08:21:11","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/odata\/?p=5967"},"modified":"2025-11-26T01:21:11","modified_gmt":"2025-11-26T08:21:11","slug":"announcing-odata-model-builder-3-0-0-preview-1-release","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/odata\/announcing-odata-model-builder-3-0-0-preview-1-release\/","title":{"rendered":"Announcing OData Model Builder 3.0.0 Preview 1 Release"},"content":{"rendered":"<p>We&#8217;re excited to announce that <strong>OData Model Builder 3.0.0 Preview 1<\/strong> has been officially released and is available on NuGet:<\/p>\n<ul>\n<li><a href=\"https:\/\/www.nuget.org\/packages\/Microsoft.OData.ModelBuilder\/3.0.0-preview.1\">Microsoft.OData.ModelBuilder 3.0.0 Preview 1<\/a><\/li>\n<\/ul>\n<p>This is a major release that brings the library up to date with the latest .NET and OData ecosystem, featuring .NET 10 support, OData Library 9.x compatibility, and modernized date\/time handling using native .NET types.<\/p>\n<h2>What&#8217;s New in OData Model Builder 3.0.0 Preview 1<\/h2>\n<h3>Framework &amp; Dependency Updates<\/h3>\n<h4>.NET 10 Support<\/h4>\n<p>OData Model Builder now targets <strong>.NET 10<\/strong>, aligning with the latest .NET runtime and taking advantage of modern performance improvements and language features. The library has moved from <code>net8.0<\/code> to <code>net10.0<\/code> as its target framework.<\/p>\n<h4>OData Library 9.x Integration<\/h4>\n<p>This release updates all OData dependencies from version 8.0.x to <strong>9.0.0-preview.3<\/strong>, ensuring full compatibility with the latest OData .NET (ODL) ecosystem:<\/p>\n<ul>\n<li><strong>Microsoft.OData.Edm<\/strong>: <code>8.0.1<\/code> \u2192 <code>9.0.0-preview.3<\/code><\/li>\n<li><strong>Microsoft.Spatial<\/strong>: <code>8.0.1<\/code> \u2192 <code>9.0.0-preview.3<\/code><\/li>\n<\/ul>\n<p>The integration includes adapting to OData Library 9.x API changes, such as the removal of the <code>CsdlTarget<\/code> parameter from CSDL writer methods. This simplifies CSDL generation and aligns with OData Library&#8217;s focus on OData CSDL exclusively (Entity Framework CSDL is no longer supported in the modern .NET Core\/EF Core ecosystem).<\/p>\n<h3>Breaking Changes: Modernized Date and Time Handling<\/h3>\n<h4>Use <code>System.DateOnly<\/code> and <code>System.TimeOnly<\/code><\/h4>\n<p>The most significant change in this release is the <strong>complete migration from legacy EDM date\/time types to .NET&#8217;s native date and time types<\/strong>. This brings OData Model Builder in line with modern .NET standards and improves consistency across the framework.<\/p>\n<p><strong>What&#8217;s Changed:<\/strong><\/p>\n<ul>\n<li><strong>Removed<\/strong>: Support for <code>Microsoft.OData.Edm.Date<\/code> and <code>Microsoft.OData.Edm.TimeOfDay<\/code><\/li>\n<li><strong>Added<\/strong>: Full support for <code>System.DateOnly<\/code> and <code>System.TimeOnly<\/code><\/li>\n<\/ul>\n<p><strong>Specific Changes:<\/strong><\/p>\n<ol>\n<li><strong>Type Mappings Removed<\/strong> from <code>EdmLibHelpers<\/code>:<\/li>\n<\/ol>\n<pre><code class=\"language-csharp\">\/\/ Removed:\r\ntypeof(Date) \u2192 EdmPrimitiveTypeKind.Date\r\ntypeof(TimeOfDay) \u2192 EdmPrimitiveTypeKind.TimeOfDay\r\n\r\n\/\/ Now using native .NET types:\r\ntypeof(DateOnly) \u2192 EdmPrimitiveTypeKind.Date\r\ntypeof(TimeOnly) \u2192 EdmPrimitiveTypeKind.TimeOfDay\r\n<\/code><\/pre>\n<ol start=\"2\">\n<li><strong>Property Configuration Methods Removed<\/strong> from <code>StructuralTypeConfiguration&lt;T&gt;<\/code>:\n<ul>\n<li><code>Property()<\/code> overloads for <code>TimeOfDay<\/code> and <code>Date<\/code> types are no longer available<\/li>\n<li>Use the standard <code>Property()<\/code> method with <code>DateOnly<\/code> and <code>TimeOnly<\/code> instead<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<h4>Migration Guidance<\/h4>\n<p>If you&#8217;re upgrading from OData Model Builder 2.x, you&#8217;ll need to update your code:<\/p>\n<p><strong>Before (2.x):<\/strong><\/p>\n<pre><code class=\"language-csharp\">using Microsoft.OData.Edm;\r\n\r\npublic class Event\r\n{\r\n    public Date EventDate { get; set; }\r\n    public TimeOfDay StartTime { get; set; }\r\n}\r\n<\/code><\/pre>\n<p><strong>After (3.0):<\/strong><\/p>\n<pre><code class=\"language-csharp\">public class Event\r\n{\r\n    public DateOnly EventDate { get; set; }\r\n    public TimeOnly StartTime { get; set; }\r\n}\r\n<\/code><\/pre>\n<p><strong>Configuration Updates:<\/strong><\/p>\n<p>All model configurations using <code>Date<\/code> or <code>TimeOfDay<\/code> properties need to be updated to use <code>DateOnly<\/code> and <code>TimeOnly<\/code>. The API surface is otherwise identical.<\/p>\n<h3>New Features<\/h3>\n<h4>Enhanced <code>TimeOnly<\/code> Support<\/h4>\n<p>To provide feature parity with existing date\/time handling, we&#8217;ve added new extension methods and helpers:<\/p>\n<ol>\n<li><strong><code>AsTimeOnly()<\/code> Extension Method<\/strong> for <code>PrimitivePropertyConfiguration<\/code>:\n<ul>\n<li>Complements the existing <code>AsTimeOfDay()<\/code> method<\/li>\n<li>Provides explicit configuration for <code>TimeOnly<\/code> properties<\/li>\n<li>Used internally by conventions like <code>ColumnAttributeEdmPropertyConvention<\/code><\/li>\n<\/ul>\n<\/li>\n<li><strong><code>IsTimeOnly()<\/code> Helper Method<\/strong> in <code>TypeHelper<\/code>:\n<ul>\n<li>Enables type detection for <code>TimeOnly<\/code> properties<\/li>\n<li>Matches the pattern of existing type helpers like <code>IsDateOnly()<\/code>, <code>IsDateTime()<\/code>, etc.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p><strong>Example Usage:<\/strong><\/p>\n<pre><code class=\"language-csharp\">var builder = new ODataConventionModelBuilder();\r\nbuilder.EntityType&lt;Event&gt;()\r\n    .Property(e =&gt; e.StartTime)\r\n    .AsTimeOnly();<\/code><\/pre>\n<h2>Why These Changes Matter<\/h2>\n<h3>Alignment with Modern .NET<\/h3>\n<p>By adopting <code>DateOnly<\/code> and <code>TimeOnly<\/code>, OData Model Builder leverages types that are:<\/p>\n<ul>\n<li><strong>Native to .NET<\/strong>: No need for custom EDM-specific types<\/li>\n<li><strong>Well-documented<\/strong>: Full framework support and documentation<\/li>\n<li><strong>Consistent<\/strong>: Same types used across .NET applications<\/li>\n<li><strong>Performant<\/strong>: Optimized by the .NET runtime<\/li>\n<\/ul>\n<h3>OData Spec Compliance<\/h3>\n<p><code>DateOnly<\/code> and <code>TimeOnly<\/code> naturally align with the OData specification&#8217;s <code>dateValue<\/code> and <code>timeOfDayValue<\/code> requirements, ensuring protocol compliance:<\/p>\n<ul>\n<li><a href=\"https:\/\/docs.oasis-open.org\/odata\/odata-csdl-json\/v4.01\/odata-csdl-json-v4.01.html#sec_Date\">OData Spec \u2013 Date<\/a><\/li>\n<li><a href=\"https:\/\/docs.oasis-open.org\/odata\/odata-csdl-json\/v4.01\/odata-csdl-json-v4.01.html#sec_TimeofDay\">OData Spec \u2013 TimeOfDay<\/a><\/li>\n<\/ul>\n<h3>Ecosystem Integration<\/h3>\n<p>This release ensures OData Model Builder works seamlessly with:<\/p>\n<ul>\n<li><strong>OData Library 9.x<\/strong>: Full compatibility with the latest OData .NET stack<\/li>\n<li><strong>.NET 10<\/strong>: Access to the latest runtime improvements and features<\/li>\n<\/ul>\n<h2>Summary<\/h2>\n<p>OData Model Builder 3.0.0 Preview 1 represents a significant step forward for the library:<\/p>\n<ul>\n<li><strong>Modern .NET alignment<\/strong>: Full .NET 10 support with native <code>DateOnly<\/code>\/<code>TimeOnly<\/code> types<\/li>\n<li><strong>Breaking changes for long-term benefit<\/strong>: Removal of legacy EDM date\/time types simplifies the API and improves maintainability<\/li>\n<li><strong>OData 9.x compatibility<\/strong>: Seamless integration with the latest OData ecosystem<\/li>\n<\/ul>\n<h2>Getting Started<\/h2>\n<p>Install the preview package from NuGet:<\/p>\n<pre><code class=\"language-bash\">dotnet add package Microsoft.OData.ModelBuilder --version 3.0.0-preview.1\r\n<\/code><\/pre>\n<p>Or add it directly to your <code>.csproj<\/code> file:<\/p>\n<pre><code class=\"language-xml\">&lt;PackageReference Include=\"Microsoft.OData.ModelBuilder\" Version=\"3.0.0-preview.1\" \/&gt;<\/code><\/pre>\n<h3>Quick Start Example<\/h3>\n<p>Here&#8217;s a complete example showing how to use the new <code>DateOnly<\/code> and <code>TimeOnly<\/code> types:<\/p>\n<p><strong>Step 1: Define your entity model<\/strong><\/p>\n<pre><code class=\"language-csharp\">public class Event\r\n{\r\n    public int Id { get; set; }\r\n    public string Title { get; set; }\r\n    public DateOnly EventDate { get; set; }\r\n    public TimeOnly StartTime { get; set; }\r\n    public TimeOnly EndTime { get; set; }\r\n    public string Location { get; set; }\r\n}\r\n<\/code><\/pre>\n<p><strong>Step 2: Build the OData model<\/strong><\/p>\n<pre><code class=\"language-csharp\">using Microsoft.OData.ModelBuilder;\r\n\r\nvar builder = new ODataConventionModelBuilder();\r\nbuilder.EntitySet&lt;Event&gt;(\"Events\");\r\n\r\nvar model = builder.GetEdmModel();\r\n<\/code><\/pre>\n<p><strong>Step 3: View the generated CSDL<\/strong><\/p>\n<p>The model builder will generate CSDL that properly maps <code>DateOnly<\/code> to <code>Edm.Date<\/code> and <code>TimeOnly<\/code> to <code>Edm.TimeOfDay<\/code>:<\/p>\n<pre><code class=\"language-xml\">&lt;?xml version=\"1.0\" encoding=\"utf-8\"?&gt;\r\n&lt;edmx:Edmx Version=\"4.0\" xmlns:edmx=\"http:\/\/docs.oasis-open.org\/odata\/ns\/edmx\"&gt;\r\n  &lt;edmx:DataServices&gt;\r\n    &lt;Schema Namespace=\"Default\" xmlns=\"http:\/\/docs.oasis-open.org\/odata\/ns\/edm\"&gt;\r\n      &lt;EntityType Name=\"Event\"&gt;\r\n        &lt;Key&gt;\r\n          &lt;PropertyRef Name=\"Id\" \/&gt;\r\n        &lt;\/Key&gt;\r\n        &lt;Property Name=\"Id\" Type=\"Edm.Int32\" Nullable=\"false\" \/&gt;\r\n        &lt;Property Name=\"Title\" Type=\"Edm.String\" \/&gt;\r\n        &lt;Property Name=\"EventDate\" Type=\"Edm.Date\" Nullable=\"false\" \/&gt;\r\n        &lt;Property Name=\"StartTime\" Type=\"Edm.TimeOfDay\" Nullable=\"false\" \/&gt;\r\n        &lt;Property Name=\"EndTime\" Type=\"Edm.TimeOfDay\" Nullable=\"false\" \/&gt;\r\n      &lt;\/EntityType&gt;\r\n      &lt;EntityContainer Name=\"Container\"&gt;\r\n        &lt;EntitySet Name=\"Events\" EntityType=\"Default.Event\" \/&gt;\r\n      &lt;\/EntityContainer&gt;\r\n    &lt;\/Schema&gt;\r\n  &lt;\/edmx:DataServices&gt;\r\n&lt;\/edmx:Edmx&gt;\r\n<\/code><\/pre>\n<p><strong>Complete working example:<\/strong><\/p>\n<pre><code class=\"language-csharp\">using Microsoft.OData.ModelBuilder;\r\nusing Microsoft.OData.Edm;\r\nusing Microsoft.OData.Edm.Csdl;\r\nusing System.Xml;\r\n\r\n\/\/ Define the entity\r\npublic class Event\r\n{\r\n    public int Id { get; set; }\r\n    public string Title { get; set; }\r\n    public DateOnly EventDate { get; set; }\r\n    public TimeOnly StartTime { get; set; }\r\n    public TimeOnly EndTime { get; set; }\r\n}\r\n\r\n\/\/ Build the model\r\nvar builder = new ODataConventionModelBuilder();\r\nbuilder.EntitySet&lt;Event&gt;(\"Events\");\r\nIEdmModel model = builder.GetEdmModel();\r\n\r\n\/\/ Write out the CSDL\r\nusing var sw = new StringWriter();\r\nusing var xw = XmlWriter.Create(sw, new XmlWriterSettings { Indent = true });\r\nCsdlWriter.TryWriteCsdl(model, xw, out var errors);\r\nxw.Flush();\r\n\r\nConsole.WriteLine(sw.ToString());\r\n<\/code><\/pre>\n<p>This example demonstrates the seamless integration of .NET&#8217;s native date and time types with OData&#8217;s EDM model, making it easier than ever to build type-safe OData services.<\/p>\n<h2>Feedback<\/h2>\n<p>This is a preview release, and we welcome your feedback! Please try the package and share your experiences on the <a href=\"https:\/\/github.com\/OData\/ModelBuilder\/issues\">GitHub repository<\/a>.<\/p>\n<p>As we work toward the final 3.0.0 release, your input will help us ensure a smooth transition for the OData Model Builder community.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>We&#8217;re excited to announce that OData Model Builder 3.0.0 Preview 1 has been officially released and is available on NuGet: Microsoft.OData.ModelBuilder 3.0.0 Preview 1 This is a major release that brings the library up to date with the latest .NET and OData ecosystem, featuring .NET 10 support, OData Library 9.x compatibility, and modernized date\/time handling [&hellip;]<\/p>\n","protected":false},"author":169392,"featured_media":3253,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1,116],"tags":[],"class_list":["post-5967","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-odata","category-odl"],"acf":[],"blog_post_summary":"<p>We&#8217;re excited to announce that OData Model Builder 3.0.0 Preview 1 has been officially released and is available on NuGet: Microsoft.OData.ModelBuilder 3.0.0 Preview 1 This is a major release that brings the library up to date with the latest .NET and OData ecosystem, featuring .NET 10 support, OData Library 9.x compatibility, and modernized date\/time handling [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/odata\/wp-json\/wp\/v2\/posts\/5967","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/odata\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/odata\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/odata\/wp-json\/wp\/v2\/users\/169392"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/odata\/wp-json\/wp\/v2\/comments?post=5967"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/odata\/wp-json\/wp\/v2\/posts\/5967\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/odata\/wp-json\/wp\/v2\/media\/3253"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/odata\/wp-json\/wp\/v2\/media?parent=5967"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/odata\/wp-json\/wp\/v2\/categories?post=5967"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/odata\/wp-json\/wp\/v2\/tags?post=5967"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}