Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add OData to Linq support #1

Merged
merged 55 commits into from
Feb 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
b9f64e3
Remove not supported TFMs
Feb 6, 2025
07e3e10
Add extension methods and unit tests from the Community.OData.Linq nuget
Feb 6, 2025
ba05b26
fix unit tests
Feb 7, 2025
b7fa529
add unit tests linked to GH issues
Feb 7, 2025
f44020a
remove comments
Feb 7, 2025
b3a9580
update xml
Feb 7, 2025
3954859
Move added code to separate project as friendly assembly
Feb 7, 2025
d784632
Specify for nuget that the OData lib is included as asset instead of …
Feb 7, 2025
e35dd4e
add extra reference to odata project in tests project
Feb 7, 2025
87c6f70
Add nuget information, add readme
Feb 7, 2025
9d18ed4
Change namespace
Feb 7, 2025
1548dd6
update version
Feb 7, 2025
86e9a87
Update readme
Feb 11, 2025
7324c09
move readme file, move OData2Linq files
Feb 11, 2025
91e572e
add a symbolic link to the odata2linq readme
Feb 11, 2025
616a2e5
instead of symlink, move readme to github folder
Feb 11, 2025
4d0851f
skip json tests, fix namespace
Feb 11, 2025
0a05a5e
add CI pipeline
Feb 11, 2025
1f83cc8
Create odata2linq-ci2.yml
ArnaudB88 Feb 11, 2025
bfd7dce
remove duplicate flow
Feb 11, 2025
8512499
rollback conflicting changes
Feb 11, 2025
4801ac9
fix pipeline
Feb 11, 2025
9adec7a
fix
Feb 11, 2025
8a5aece
fix TMFs
Feb 11, 2025
1dbd36e
fix net8
Feb 11, 2025
6403933
fix tmf
Feb 11, 2025
cae726c
fix conflicts
Feb 11, 2025
5a4aa09
fix
Feb 11, 2025
bf02db4
Revert "remove duplicate flow"
Feb 11, 2025
f1fd487
Merge branch 'feature/odata-link810' of https://github.com/ArnaudB88/…
Feb 11, 2025
03710ce
rollback all TMF changes
Feb 11, 2025
eafef19
Add Benchmark project
Feb 12, 2025
ea3c0a0
Fix hashing which only constructs one container per setting (for perf…
Feb 12, 2025
ac848cd
remove unneeded registrations and old code
Feb 12, 2025
65c24e9
fix unit test, code cleanup
Feb 12, 2025
b31a26f
Set odata2linq to v1.0.0
Feb 13, 2025
5c69c08
Add test for timeonly
Feb 13, 2025
f8af327
add CD pipeline
Feb 13, 2025
da4d962
fix unit tests if executed on a machine with UTC as timezone, specify…
Feb 13, 2025
f887b25
fix unit tests
Feb 13, 2025
7d77f50
fix last failing test
Feb 13, 2025
ed8996f
pipeline fix
Feb 13, 2025
121ac6f
Set package version to 1.0.0
Feb 13, 2025
d201009
Add package description
Feb 13, 2025
0c4d5ea
fix readme nuget links
Feb 14, 2025
f61574a
Correctly implement a memory usage test
Feb 14, 2025
41d1462
rename property
Feb 14, 2025
015a773
add comments
Feb 14, 2025
76fa94d
update MS.AspNetCore.Odata readme with link to OData2Linq readme
Feb 17, 2025
f29b69d
fix merge conflicts
Feb 17, 2025
a6f5111
Merge branch 'feature/odata-link825' into feature/odata-link810
Feb 17, 2025
a6f6c08
Merge with ASP.NET Core OData to v8.2.5, bump OData2Linq version to v…
Feb 17, 2025
bcd15fe
fix merge conflict in readme
Feb 17, 2025
1f7df83
fix build in pipeline
Feb 17, 2025
56c379d
undo last commit to fix merge conflicts
Feb 17, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 107 additions & 0 deletions .github/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
[![NuGet Version](https://img.shields.io/nuget/v/OData2Linq?label=NuGet)](https://www.nuget.org/packages/OData2Linq/)

# OData2Linq
Apply an OData text query (filter, order by, select, ..) to an IQueryable expression.

# Features
- Manipulate an IQueryable expression with OData text query

## Supported OData parameters
| Params | In Memory Collections | Entity Framework | CosmosDB SQL API |
| ------------- |:---------------------:|:----------------:| :---------------:|
| $filter |+ | + | + |
| $orderby |+ | + | + |
| $select |+ | + | - |
| $expand |+ | + | - |
| $top |+ | + | + |
| $skip |+ | + | + |

# Samples
Please check samples below to get started

## .NET Fiddle
https://dotnetfiddle.net/6dLB2g

## Console app
```csharp
using System;
using System.Linq;
using OData2Linq;

public class Entity
{
public int Id { get; set; }
public string Name { get; set; }
}

public static class GetStartedDemo
{
public static void Demo()
{
Entity[] items =
{
new Entity { Id = 1, Name = "n1" },
new Entity { Id = 2, Name = "n2" },
new Entity { Id = 3, Name = "n3" }
};
IQueryable<Entity> query = items.AsQueryable();

var result = query.OData().Filter("Id eq 1 or Name eq 'n3'").OrderBy("Name desc").TopSkip("10", "0").ToArray();

// Id: 3 Name: n3
// Id: 1 Name: n1
foreach (Entity entity in result)
{
Console.WriteLine("Id: {0} Name: {1}", entity.Id, entity.Name);
}
}
}
```

## Support ToArrayAsync(), ToListAsync(), and all other provider specific methods.
Use `.ToOriginalQuery()` after finishing working with OData to be able to support provider specific methods of original query.

### Entity Framework async data fetch.
```
Student[] array = await dbContext.Students.OData()
.Filter("LastName eq 'Alexander' or FirstMidName eq 'Laura'")
.OrderBy("EnrollmentDate desc")
.TopSkip("1","1")
.ToOriginalQuery() // required to be able to use .ToArrayAsync() next.
.ToArrayAsync();

ISelectExpandWrapper[] select2 = await dbContext.Students.OData()
.Filter("LastName eq 'Alexander' or FirstMidName eq 'Laura'")
.OrderBy("EnrollmentDate desc")
.SelectExpandAsQueryable("LastName", "Enrollments($select=CourseId)") //.SelectExpandAsQueryable() use .ToOriginalQuery() implicitly, so not need to call it.
.ToArrayAsync()
```
### CosmosDb SQL API async data fetch.
```
var item = await Container.GetItemLinqQueryable<TestEntity>().OData()
.Filter($"Id eq '{id1}'")
.TopSkip("1")
.ToOriginalQuery() // required to be able to use .ToFeedIterator() next.
.ToFeedIterator()
.ReadNextAsync()
```

## Advanced code samples at wiki
See the [Wiki pages](https://github.com/ArnaudB88/OData2Linq/wiki)

# Contribution
Please feel free to create issues and pull requests to the main branch.

# Nuget
| Package | NuGet | Info |
|---------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------|------------------|
| OData2Linq | [![NuGet Version](https://img.shields.io/nuget/v/OData2Linq?label=NuGet)](https://www.nuget.org/packages/OData2Linq/) | OData v8 support |
| Community.OData.Linq.Json | [![NuGet Version](https://img.shields.io/nuget/v/Community.OData.Linq.Json)](https://www.nuget.org/packages/Community.OData.Linq.Json) | Still works on odata v7 libraries. Open an issue to create a new package for odata v8. |
| Community.OData.Linq.AspNetCore | [![NuGet Version](https://img.shields.io/nuget/v/Community.OData.Linq.AspNetCore)](https://www.nuget.org/packages/Community.OData.Linq.AspNetCore) | Still works on odata v7 libraries. Open an issue to create a new package for odata v8. |

# References
This project is based on the following project:
https://github.com/IharYakimush/comminity-data-odata-linq

The repository is a fork from:
https://github.com/OData/AspNetCoreOData
34 changes: 34 additions & 0 deletions .github/workflows/odata2linq-cd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# This workflow will build a .NET project
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-net

name: odata2linq-cd

on:
push:
tags:
- 'OData2Linq_*.*.*'

jobs:
build:

runs-on: windows-latest
strategy:
matrix:
dotnet-version: ['6.0.x']

steps:
- uses: actions/checkout@v4
- name: Setup dotnet ${{ matrix.dotnet-version }}
uses: actions/setup-dotnet@v4
with:
dotnet-version: ${{ matrix.dotnet-version }}
- name: Restore dependencies
run: dotnet restore ./AspNetCoreOData.sln
- name: Build
run: dotnet build ./AspNetCoreOData.sln -c Release --no-restore
- name: Test
run: dotnet test ./AspNetCoreOData.sln -c Release --no-build --verbosity normal
- name: Pack
run: dotnet pack ./src/OData2Linq/OData2Linq.csproj -c Release -o .\artifacts --no-build
- name: Publish to NuGet
run: dotnet nuget push .\artifacts\*.nupkg --source https://api.nuget.org/v3/index.json --api-key ${{ secrets.NUGET_API_KEY }}
31 changes: 31 additions & 0 deletions .github/workflows/odata2linq-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# This workflow will build a .NET project
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-net

name: odata2linq-ci

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

jobs:
build:

runs-on: windows-latest
strategy:
matrix:
dotnet-version: ['6.0.x']

steps:
- uses: actions/checkout@v4
- name: Setup dotnet ${{ matrix.dotnet-version }}
uses: actions/setup-dotnet@v4
with:
dotnet-version: ${{ matrix.dotnet-version }}
- name: Restore dependencies
run: dotnet restore ./AspNetCoreOData.sln
- name: Build
run: dotnet build ./AspNetCoreOData.sln --no-restore
- name: Test
run: dotnet test ./AspNetCoreOData.sln --no-build --verbosity normal
23 changes: 22 additions & 1 deletion AspNetCoreOData.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.3.32901.215
VisualStudioVersion = 17.12.35707.178
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{2F0E102B-EB33-4025-BE56-7B8F9D2C4B8A}"
EndProject
Expand All @@ -19,6 +19,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.OData.
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.OData.TestCommon", "test\Microsoft.AspNetCore.OData.TestCommon\Microsoft.AspNetCore.OData.TestCommon.csproj", "{9DB7ACCB-79CC-495C-A145-BC50A7733A21}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OData2Linq", "src\OData2Linq\OData2Linq.csproj", "{568A35C2-8677-41C6-9098-3AEF23286A9E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OData2Linq.Tests", "test\OData2Linq.Tests\OData2Linq.Tests.csproj", "{E7F48129-7544-4D85-ABE1-4CB037E1C780}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OData2Linq.Benchmark", "test\OData2Linq.Benchmark\OData2Linq.Benchmark.csproj", "{11B8ED5C-E54C-46A4-A5A7-E880E5EC634E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ODataCustomizedSample", "sample\ODataCustomizedSample\ODataCustomizedSample.csproj", "{BDC5474B-9511-4CDF-83FE-376C7130F7F0}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ODataDynamicModel", "sample\ODataDynamicModel\ODataDynamicModel.csproj", "{CE04E38B-547F-46C0-ABE4-F981E3A1874F}"
Expand Down Expand Up @@ -55,6 +61,18 @@ Global
{9DB7ACCB-79CC-495C-A145-BC50A7733A21}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9DB7ACCB-79CC-495C-A145-BC50A7733A21}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9DB7ACCB-79CC-495C-A145-BC50A7733A21}.Release|Any CPU.Build.0 = Release|Any CPU
{568A35C2-8677-41C6-9098-3AEF23286A9E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{568A35C2-8677-41C6-9098-3AEF23286A9E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{568A35C2-8677-41C6-9098-3AEF23286A9E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{568A35C2-8677-41C6-9098-3AEF23286A9E}.Release|Any CPU.Build.0 = Release|Any CPU
{E7F48129-7544-4D85-ABE1-4CB037E1C780}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E7F48129-7544-4D85-ABE1-4CB037E1C780}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E7F48129-7544-4D85-ABE1-4CB037E1C780}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E7F48129-7544-4D85-ABE1-4CB037E1C780}.Release|Any CPU.Build.0 = Release|Any CPU
{11B8ED5C-E54C-46A4-A5A7-E880E5EC634E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{11B8ED5C-E54C-46A4-A5A7-E880E5EC634E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{11B8ED5C-E54C-46A4-A5A7-E880E5EC634E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{11B8ED5C-E54C-46A4-A5A7-E880E5EC634E}.Release|Any CPU.Build.0 = Release|Any CPU
{BDC5474B-9511-4CDF-83FE-376C7130F7F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BDC5474B-9511-4CDF-83FE-376C7130F7F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BDC5474B-9511-4CDF-83FE-376C7130F7F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand Down Expand Up @@ -85,6 +103,9 @@ Global
{FF17DFD5-7ED0-433F-8DD9-4576E0CFFFBA} = {F994C269-55BA-44F0-9DA7-6D5A3CFA79EB}
{E428817E-A93C-4C1F-9D20-F5CA8C3627C1} = {F994C269-55BA-44F0-9DA7-6D5A3CFA79EB}
{9DB7ACCB-79CC-495C-A145-BC50A7733A21} = {F994C269-55BA-44F0-9DA7-6D5A3CFA79EB}
{568A35C2-8677-41C6-9098-3AEF23286A9E} = {2F0E102B-EB33-4025-BE56-7B8F9D2C4B8A}
{E7F48129-7544-4D85-ABE1-4CB037E1C780} = {F994C269-55BA-44F0-9DA7-6D5A3CFA79EB}
{11B8ED5C-E54C-46A4-A5A7-E880E5EC634E} = {F994C269-55BA-44F0-9DA7-6D5A3CFA79EB}
{BDC5474B-9511-4CDF-83FE-376C7130F7F0} = {B1F86961-6958-4617-ACA4-C231F95AE099}
{CE04E38B-547F-46C0-ABE4-F981E3A1874F} = {B1F86961-6958-4617-ACA4-C231F95AE099}
{647EFCFA-55A7-4F0A-AD40-4B6EB1BFCFFA} = {B1F86961-6958-4617-ACA4-C231F95AE099}
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# ASP.NET Core OData 8.x
---

For the OData2Linq readme, [click here](https://github.com/ArnaudB88/OData2Linq).

---

Component | Build | Status
--------|--------- |---------
ASP.NET Core OData|Rolling | [![Build status](https://identitydivision.visualstudio.com/OData/_apis/build/status/AspNetCoreOData/AspNetCoreOData-main-rolling)](https://identitydivision.visualstudio.com/OData/_build/latest?definitionId=1132)
Expand Down
30 changes: 14 additions & 16 deletions src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1102,6 +1102,20 @@
<param name="clrType">The type to test.</param>
<returns>True if the type is a DateTime; false otherwise.</returns>
</member>
<member name="M:Microsoft.AspNetCore.OData.Common.TypeHelper.IsDateOnly(System.Type)">
<summary>
Determine if a type is a <see cref="T:System.DateOnly"/>.
</summary>
<param name="clrType">The type to test.</param>
<returns>True if the type is a DateOnly; false otherwise.</returns>
</member>
<member name="M:Microsoft.AspNetCore.OData.Common.TypeHelper.IsTimeOnly(System.Type)">
<summary>
Determine if a type is a <see cref="T:System.TimeOnly"/>.
</summary>
<param name="clrType">The type to test.</param>
<returns>True if the type is a TimeOnly; false otherwise.</returns>
</member>
<member name="M:Microsoft.AspNetCore.OData.Common.TypeHelper.IsTimeSpan(System.Type)">
<summary>
Determine if a type is a TimeSpan.
Expand Down Expand Up @@ -15579,19 +15593,3 @@
</member>
</members>
</doc>
ummary>
<param name="segment">The value segment.</param>
</member>
<member name="P:Microsoft.AspNetCore.OData.Routing.Template.ValueSegmentTemplate.Segment">
<summary>
Gets the value segment.
</summary>
</member>
<member name="M:Microsoft.AspNetCore.OData.Routing.Template.ValueSegmentTemplate.GetTemplates(Microsoft.AspNetCore.OData.Routing.ODataRouteOptions)">
<inheritdoc />
</member>
<member name="M:Microsoft.AspNetCore.OData.Routing.Template.ValueSegmentTemplate.TryTranslate(Microsoft.AspNetCore.OData.Routing.Template.ODataTemplateTranslateContext)">
<inheritdoc />
</member>
</members>
</doc>
2 changes: 2 additions & 0 deletions src/Microsoft.AspNetCore.OData/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,5 @@
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.OData.E2E.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9")]

[assembly: InternalsVisibleTo("Microsoft.AspNetCore.OData.NewtonsoftJson.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9")]

[assembly: InternalsVisibleTo(assemblyName: "OData2Linq, PublicKey=00240000048000009400000006020000002400005253413100040000010001009d992fba5d4cbb3d67a46a65d01094fac14c4d8269c76dfe22a2447b37ed7339fb906d08d84a44bd8fe496bdab1a4d49c0a5df61600349d7a4708da1df0e4e22e726d830957a8ab2aba161633728e45561b078ee89c5c5afef23379499bee69c0b70e8039d09f11d0817e65cfd3848f2a6a2db0e75e767f596ff28d25c8acadb")]
Binary file added src/OData2Linq/FriendAssemblies.snk
Binary file not shown.
Loading
Loading