Skip to content

Conversation

@WanjohiSammy
Copy link
Member

@WanjohiSammy WanjohiSammy commented Nov 22, 2025

Issues

This pull request fixes issue #xxx.

Description

This PR updates Microsoft.OData.ModelBuilder to version 3.0.0-preview.1, targeting .NET 10 and OData Library 9.0.0-preview.3.

Changes

Version & Framework Updates

  • Bumped major version from 2.x to 3.0.0-preview.1
  • Updated target framework from net8.0 to net10.0
  • Updated OData dependencies from 8.0.x to 9.0.0-preview.3

Breaking Changes

  • Removed support for Microsoft.OData.Edm.Date and TimeOfDay types: The library now exclusively uses .NET's native DateOnly and TimeOnly types
    • Removed Date and TimeOfDay type mappings from EdmLibHelpers
    • Removed Property() overloads for TimeOfDay and Date types from StructuralTypeConfiguration<T>
    • Updated IsDateOnly() to use direct type comparison instead of string-based lookup

New Features

  • Added AsTimeOnly() extension method for PrimitivePropertyConfiguration (complements existing AsTimeOfDay())
  • Added IsTimeOnly() helper method in TypeHelper
  • Added new resource string MustBeTimeOnlyProperty for validation

Updates & Fixes

  • Updated ColumnAttributeEdmPropertyConvention to use AsTimeOnly() for time column types
  • Updated CSDL writer usage to match new OData 9.x API signature (removed CsdlTarget.OData parameter)
  • Fixed exception handling in test utilities to work with updated xunit API
  • Updated test dependencies:
    • xunit: 2.3.1 → 2.9.3
    • xunit.runner.visualstudio: 2.3.1 → 3.0.2
    • Microsoft.NET.Test.Sdk: 15.3.0 → 17.14.1
  • Updated T4 template assembly reference to OData Edm 9.0.0-preview.3

Testing

  • All tests updated to use DateOnly/TimeOnly instead of Date/TimeOfDay
  • Updated public API baseline to reflect new signatures
  • Test models and scenarios updated to match new type system

Related Issues

This update aligns with the OData ecosystem's migration to .NET 10 and OData Library 9.x.

Checklist (Uncheck if it is not completed)

  • Test cases added
  • Build and test with one-click build and test script passed

Additional work necessary

If documentation update is needed, please add "Docs Needed" label to the issue and provide details about the required document change in the issue.

@WanjohiSammy
Copy link
Member Author

/AzurePipelines run

@azure-pipelines
Copy link

No pipelines are associated with this pull request.

/// </summary>
/// <param name="property">Reference to the calling primitive property configuration.</param>
/// <returns>Returns itself so that multiple calls can be chained.</returns>
public static PrimitivePropertyConfiguration AsTimeOfDay(this PrimitivePropertyConfiguration property)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does TimeOfDay here need to change?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is public, we can mark as Obsolete in 2.x and remove it here completely. For now, I have added another public method called AsTimeOnly(...).
Same applied to AsDate(...)

throw Error.ArgumentNull("property");
}

if (!TypeHelper.IsTimeSpan(property.RelatedClrType) && !TypeHelper.IsTimeOnly(property.RelatedClrType))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I understand the logic here... We're check if the CLR type is TimeSpan or TimeOnly and if not, we're thrown an exception saying the CLR type for the property must be a TimeSpan. Please explain

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The AsDateOnly(...) extension method sets the property's target EDM type to EdmPrimitiveTypeKind.Date when the property is of type System.DateTime or System.DateOnly, ensuring the property is treated as a date in the OData metadata.

The AsTimeOnly(...) extension method sets the property's target EDM type to EdmPrimitiveTypeKind.TimeOfDay when the property is of type System.TimeSpan or System.TimeOnly.

property.DeclaringType.FullName);
}

property.TargetEdmTypeKind = EdmPrimitiveTypeKind.TimeOfDay;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was the TimeOfDay enum member going to change to TimeOnly or did we decide to save ourselves the trouble?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TimeOfDay and Date as EdmPrimitiveTypeKind enum members will remain as they are for now. But eventually, we will have to rename them correctly.

/// </summary>
/// <param name="property">Reference to the calling primitive property configuration.</param>
/// <returns>Returns itself so that multiple calls can be chained.</returns>
public static PrimitivePropertyConfiguration AsTimeOnly(this PrimitivePropertyConfiguration property)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, I'm a bit confused here. This method is named AsTimeOnly but inside the body, we only if the CLR type of the property is TimeSpan and throw an exception if it is not

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The AsDateOnly(...) extension method sets the property's target EDM type to EdmPrimitiveTypeKind.Date when the property is of type System.DateTime or System.DateOnly, ensuring the property is treated as a date in the OData metadata.

The AsTimeOnly(...) extension method sets the property's target EDM type to EdmPrimitiveTypeKind.TimeOfDay when the property is of type System.TimeSpan or System.TimeOnly.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@WanjohiSammy Why can't one of AsTimeOfDay and AsTimeOnly call the other instead of duplicating the code? Maybe AsTimeOfDay should call AsTimeOnly since AsTimeOfDay is what we might deprecate in the future?

Same argument around AsDate and AsDateOnly

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gathogojr This is updated with this commit b25d32e

@gathogojr
Copy link
Contributor

@WanjohiSammy The base for your pull request should be https://github.com/OData/ModelBuilder/tree/dev-3.x not main

<!-- For NuGet Package Dependencies -->
<PropertyGroup>
<ODataLibPackageDependency>[8.0.0, 9.0.0)</ODataLibPackageDependency>
<ODataLibPackageDependency>[9.0.0-preview.3, 10.0.0)</ODataLibPackageDependency>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curious if this works

Copy link
Member Author

@WanjohiSammy WanjohiSammy Nov 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gathogojr This should work. It ensures the package uses ODL ≥ 9.0.0-preview.3 and < 10.0.0

Copy link
Member Author

@WanjohiSammy WanjohiSammy Nov 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could bump the version in a different PR

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@WanjohiSammy I think the version is fine. What I was curious about is whether the part -preview.3 is evaluated as expected

@WanjohiSammy WanjohiSammy changed the base branch from main to dev-3.x November 23, 2025 10:57
branches:
include:
- main
- release-1.x
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should add dev-3.x rather replace release-1.x, just in case one was to create a pull request against the release-1.x branch

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is updated through commit 43762ce

displayName: midnightly build
branches:
include:
- main
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to add dev-3.x here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should have dev-3.x here as well. Updated with commit 43762ce

@WanjohiSammy WanjohiSammy merged commit c5dca54 into dev-3.x Nov 24, 2025
2 checks passed
@WanjohiSammy WanjohiSammy deleted the fix/update-to-3_x branch November 24, 2025 08:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants