bcc-linq's People
bcc-linq's Issues
Add support for ThenInclude(...) on Enumerables
Currently .ThenInclude(...) only works after a non-enumerable object. Often it needs to be applied to an enumerable.
For example.
client.Persons.GetQueryable().Include(p => p.Affiliations).ThenInclude(a => a.Org)
Note that Affiliations in the example above is a List of affiliations.
Implement `FetchAsync`
We should implement FetchAsync which is currently implemented in the Core API here
Include and ThenInclude don't use JSON serialization settings when converting field to string
Example:
public class MyEntity
{
[DataMember(Name = "other_entity")]
[JsonProperty("other_entity")]
public OtherEntity OtherEntity { get; set; }
//...
}
...
var result = await client.MyEntities.Query().Include(e => e.OtherEntity).ToListAsync();
The above code results in fields=*,otherEntity.*
in the query. The expected behaviour would be fields=*,other_entity.*
if either DataMember or JsonProperty attributes are used with a name override.
The same applies to any query where the fields appear in the filter.
Tuple on _between does not work correct
Rename library to `BccCode.Linq`
Reng and @leo-schick had a chat about the library name and we decided that it shall be changed to BccCode.Linq
.
Fix handling of enumerable fields in collection list
Nullable types
If you're filtering on a nullable type the the ApplyRuleFilter
throws an exception:
Contributions.Contracts.Standard.Exceptions.ApiRequestException : Failed to retrieve data from /contributions/Projects?limit=100&page=1. Status code: BadRequest. Content: {"error":{"code":null,"message":"Expression of type 'System.Nullable1[System.DateTime]' cannot be used for parameter of type 'System.Object' of method 'Double ToDouble(System.Object)' (Parameter 'arg0')"},"errors":[]}
{
var filter = new Filter(jsonFilter);
basicQuery = basicQuery.ApplyRuleFilter(filter);
}```
Add extension function to apply IApiRequest on a IQueryable object
The current ApplyRuleFilter
extension method makes it possible to apply a filter on IQueryable. But there are many other options like limit
, offset
, aggregte
, sort
, fields
which we could apply to IQueryable.
I suggest to add a new IQueryable<TSource> ApplyApiRequest<TSource>(IApiRequest)
which applies the IApiRequest properties Fields
, Filter
, Sort
, Limit
, Offset
, Page
, GroupBy
, Deep
and Alias
in a single extension method. The IApiRequest properties Meta
and Aggregate
are not implemented by this.
Linq support for selecting Scalar
Linq queries selecting a scalar value are not possible. For example, calling
var query = from p in api.Persons
select p.Age;
is not possible, but
var query = from p in api.Persons
select new { p.Age };
is possible.
It is easy to use the workaround given above (introducing an anonymous type in the select clause), but this restriction does not allow us to use aggregat functions like this:
double averageAge = (
from p in api.Persons
select p.Age
).Average();
Filtering by nested property on collection does not work
RuleFilsterParser follow-up: add, and handle missing cases
- add missing cases in tests
- handle all the cases in the code
Implement `Include`
We should implement Include which is currently implemented in the Core API here
Server-side `ToString()` support in `filter` operations
Using ToString() in a
filter` operation should be supported on server-side proprerties. Example:
var query =
from p in api.Persons.AsQueryable()
where p.Uid.ToString() == "70a10bd7-7912-4451-84e8-82ad45408c0c"
select p;
Improve DateTime parsing
Date formatted like ""yyyy-mm-dd"
in filter value should be cast to DateTime
but it's string
Implement QueryProvider for converting from IQueryable to Json string
We already have a json parser for Directus format and we need an implementation of a QueryProvider that will be used for conversion from IQueryable to a query string.
Check the implementation of a QueryProvider here:
https://github.com/bcc-code/bcc-core-api/tree/main/sdk/dotnet/src
We want to copy that part into this repository and make it available for all projects using rule-filter-parser-dotnet nuget package.
Filter object for SDK Client
For Core API (api.bcc.no), we're using directus format for filtering and we send it as a query parameter to an endpoint like this:
Task<CollectionResponse<ContributionRead>> Get(
string jsonFilter,
int pageNumber = 1,
int itemsPerPage = 100,
CancellationToken cancellationToken = default);
It doesn't make much sense using SDK Client if we need to still provide a json formatted string for filters. The idea is to create a C# implementation (Linq) that allows us to create a filter dynamically without taking care of validation of the filter.
How it could be used:
var json = DirectusFilterBuilder<Project>.Create()
.Where(x => x.Status == true)
.Serialize();
We will focus on simple where operations:
- Equal
- GreaterThanOrEqual
- LessThanOrEqual
- GreaterThan
- LessThan
- IsTrue
- IsFalse
- operations for navigated properties
- OR operations
GitHub Action check-format always fails
The implemented GitHub Action check-format always fails in pull requests, marking the pull requests always with a red cross.
Please fix the GitHub Actions check-format or remove it @piotrczyz
RuleFilterParser handle int values in the filter
int, long, double values are always parsed as double, in the result it makes type mismatch with db entities.
Example RegistrationHours endpoint in Contribution API
Sending { "registrationId":{"_eq": 333755}} in the filter returns error because registrationId is type nullable Int32 but this value provided in the filter is always parsed to double
[Epic] Advanced Linq Queryable support
This is a collection ticket for improvements of the QueryProvider introduced via #20
Queryable Implementation matrix
When it is not implemented, the default behavior applies --> meaning: the query is performed on client side, possibly running heavy API loads against the API.
IQueryable function | Implemented | Unit tests exist |
---|---|---|
Aggregate | No | No |
All | No | No |
Any | ✔️ #51 | ✔️ #51 |
Append | No | No |
Average | ✔️ |
No |
Cast | No | No |
Chunk | No | No |
Concat | No | No |
Contains | No | No |
Count | ✔️ |
No |
DefaultIfEmpty | No | No |
Distinct | No | No |
DistinctBy | No | No |
ElementAt | ✔️ #42 | ✔️ #42 |
ElementAtOrDefault | ✔️ #42 | ✔️ #42 |
Except | No | No |
ExceptBy | No | No |
First | ✔️ #42 | ✔️ #42 |
FirstOrDefault | ✔️ #42 | ✔️ #42 |
GroupBy | No | No |
GroupJoin | No | No |
Intersect | No | No |
IntersectBy | No | No |
Join | No | No |
Last | No, require revert sorting | No |
LastOrDefault | No, require revert sorting | No |
LongCount | ✔️ |
No |
Max | ✔️ |
No |
MaxBy | No | No |
Min | ✔️ |
No |
MinBy | No | No |
OfType | No | No |
Order | No | No |
OrderBy | ✔️ | ✔️ |
OrderByDescending | ✔️ | ✔️ |
Prepend | No | No |
Reverse | No, easily possible | No |
Select | ✔️ | ✔️ |
SelectMany | No | No |
SequenceEqual | No | No |
SequenceEqual | No | No |
Single | ✔️ #42 | ✔️ #42 |
SingleOrDefault | ✔️ #42 | ✔️ #42 |
Skip | ✔️ | ✔️ #30 |
SkipLast | No, require revert sorting | No, require revert sorting |
SkipWhile | No | No |
Sum | ✔️ |
No |
Take | ✔️ | ✔️ #30 |
TakeLast | No, require revert sorting | No, require revert sorting |
TakeWhile | No | No |
ThenBy | ✔️ | ✔️ |
ThenByDescending | ✔️ | ✔️ |
Union | No | No |
UnionBy | No | No |
Where | ✔️ | ✔️ |
Zip | No | No |
Other topics
- make async calls possible, e.g.
ToListAsync
orawait foreach(var p in myQuery)
#29 - revert sorting required for
...Last
linq methods https://github.com/bcc-code/bcc-core-api/issues/367
Add documentation for ApplyApiRequest
Add documentation for ApplyApiRequest
method
IQueryable support
The package requires the ability to apply a rule filter on the IQueryable
collection. At the moment it is only possible to use it on IEnumerable
which is not enough if we want to handle database level filtering.
Linq Queryable support for selector parameter in aggregate functions
Linq brings multiple aggregate functions; Average
, Count
, LongCount
, Max
, Min
, Sum
Currently it is not possible to use them. They are implemented without parameter, but cannot be used because of #26.
In addition, it would be great to have them implemented with parameter so that you can call them like this:
Call aggregation with property
double averageAge = api.Persons.Average(p => p.Age);
This option requires to have at least one row, otherwise Linq will crash because you cannot put null
into double
.
Call aggregation with property casted to null
double? averageAge = api.Persons.Average(p => (double?)p.Age);
This option will work when you have no row at all returning null
.
Null checks in query don't result in expected JSON
Currently e.Parent.Id == null
in a Linq query results in:
{ "parentId": { "_eq" : null }}
The expected directus-syntax is:
{ "parentId": { "_null" : true }}
for != null
the expected syntax would be:
{ "parentId": { "_nnull" : true}}
Implement `ThenInclude`
With #37 we implement Include
on just base level. Additional, we would like to add ThenInclude
to define including/extending nested data from already nested data. e.g. api.Persons.Include(p => p.Car).ThenInclude(p.Manufacture)
This requires to implement interface IIncludableQueryable
and return it in Include. This is required to implement ThenInclude.
The links refer to the EF Core implementation of such a logic.
Implement Async for QueryProvider
Currently Async operations are not implemented for the QueryProvider introduced via #20
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.