iharyakimush / comminity-data-odata-linq Goto Github PK
View Code? Open in Web Editor NEWUse OData filter text query in linq expresson for any IQuerable without ASP.NET dependency. Support netstandard2.0
License: Other
Use OData filter text query in linq expresson for any IQuerable without ASP.NET dependency. Support netstandard2.0
License: Other
When I specify property name in select it throws the following exception
Could not create an instance of type Community.OData.Linq.OData.Query.Expressions.PropertyContainer.
Type is an interface or abstract class and cannot be instantiated. Path '[0].Container.Name', line 1, position 71
I'm using this package to query CosmosDB and GetItemLinqQueryable. Any ideas on how to approach this issue?
When I specify property name in select it throws the following exception
Could not create an instance of type Community.OData.Linq.OData.Query.Expressions.PropertyContainer.
Type is an interface or abstract class and cannot be instantiated. Path '[0].Container.Name', line 1, position 71
I'm using this package to query CosmosDB and GetItemLinqQueryable. Any ideas on how to approach this issue?
We're making use of the Library version 1.4.0.0 and we're having some issues with some OData queries which have an expand depth higher than 2.
"The request includes a $expand path which is too deep. The maximum depth allowed is 2. To increase the limit, set the 'MaxExpansionDepth' property on EnableQueryAttribute or ODataValidationSettings, or set the 'MaxDepth' property in ExpandAttribute"
My question in this regards is if ( and how ) is it possible to override the default value of 2, which seems to be set by default on ODataSettings.cs (ODataValidationSettings class).
Can you please help us find a way ?
Thank you very much.
Great work.
Best regards,
Nuno Batalha
Hello,
The OData
Linq Extension has a memory leak. A ServiceContainer
object is getting created, however, it's never disposed. This causes CPU usage to spike over time.
I created a fix. I wanted to submit a pull request, however, I was unable to do so on this repo. The changes I made are limited. It would be super helpful if these changes could be integrated and a new NuGet package get published. The changes are in two files:
Community.Data.OData.Linq/ODataQuery.cs
Added IDisposable
interface to the class.
public class ODataQuery<T> : IQueryable<T>, IDisposable
Implemented the Dispose
method.
public void Dispose()
{
if (this.ServiceProvider != null)
{
if (this.ServiceProvider is IDisposable)
{
((IDisposable)(this.ServiceProvider)).Dispose();
}
}
}
Community.Data.OData.Linq.xTests
Added test of Dispose
method
[Fact]
public void Disposable()
{
// Generate the list of items to query
var items = new List<TestItem>();
items.Add(new TestItem() { Id = Guid.NewGuid(), Name = "Test", Number = 1 });
items.Add(new TestItem() { Id = Guid.NewGuid(), Name = "Another", Number = 2 });
var odata = items.AsQueryable().OData();
var filteredItems = odata.Filter("Number eq 2");
odata.Dispose(); // Test that the OData object is being torn down
Assert.Equal(1, filteredItems.Count());
}
Added TestItem
class for testing needs
/// <summary>
/// A utility class for use in ODataTests
/// </summary>
public class TestItem
{
public Guid Id { get; set; }
public string Name { get; set; }
public int Number { get; set; }
}
This causes BindDynamicPropertyAccessQueryNode to throw a NullReferenceException when BindPropertyAccessExpression tries to access prop.Name.
Some Filter queries with open types can't be parsed. I believe this issue exists in the official OData package too and relates to OData/WebApi#445
I try to filter EF entities with Filter
with net6.0 but that throw a TypeInitializationException
:
public static ODataQuery<T> GetODataQuery<T>(this IQueryable<T> query, string filter, IEdmModel edmModel = null) where T: class
{
var odataQuery = query.OData(edmModel: edmModel);
if (!string.IsNullOrEmpty(filter))
{
odataQuery = odataQuery.Filter(filter);
}
return odataQuery;
}
System.TypeInitializationException: The type initializer for 'Community.OData.Linq.OData.Query.Expressions.ExpressionBinderBase' threw an exception.
---> System.InvalidOperationException: Sequence contains more than one matching element
at System.Linq.ThrowHelper.ThrowMoreThanOneMatchException()
at System.Linq.Enumerable.TryGetSingle[TSource](IEnumerable`1 source, Func`2 predicate, Boolean& found)
at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source, Func`2 predicate)
at Community.OData.Linq.OData.Query.Expressions.ExpressionBinderBase..cctor()
--- End of inner exception stack trace ---
at Community.OData.Linq.OData.Query.Expressions.ExpressionBinderBase.CreateBinaryExpression(BinaryOperatorKind binaryOperator, Expression left, Expression right, Boolean liftToNull)
at Community.OData.Linq.OData.Query.Expressions.FilterBinder.BindBinaryOperatorNode(BinaryOperatorNode binaryOperatorNode)
at Community.OData.Linq.OData.Query.Expressions.FilterBinder.Bind(QueryNode node)
at Community.OData.Linq.OData.Query.Expressions.FilterBinder.BindExpression(SingleValueNode expression, RangeVariable rangeVariable, Type elementType)
at Community.OData.Linq.OData.Query.Expressions.FilterBinder.BindFilterClause(FilterBinder binder, FilterClause filterClause, Type filterType)
at Community.OData.Linq.OData.Query.Expressions.FilterBinder.Bind(IQueryable baseQuery, FilterClause filterClause, Type filterType, IServiceProvider requestContainer)
at Community.OData.Linq.ODataLinqExtensions.Filter[T](ODataQuery`1 query, String filterText, String entitySetName)
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.0-preview.3.21201.2" />
<PackageReference Include="Community.OData.Linq.Json" Version="1.4.2" />
Same code works on net5.0.
Hi there,
We are working with an EF (6.2) generated model and using Community.OData.Linq.
When try to query we are getting an exception:
The complex type 'D_Geography' has a reference to itself through the property 'D_Geography1'. A recursive loop of complex types is not allowed.
This exception is thrown when querying entity:
public partial class F_Comparable { [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] public F_Comparable() { this.F_Comparable_Attribute = new HashSet<F_Comparable_Attribute>(); this.F_Comparable1 = new HashSet<F_Comparable>(); this.F_Comparable_Measure = new HashSet<F_Comparable_Measure>(); } public long ComparableID { get; set; } public long CountryID { get; set; } public string ComparableCode { get; set; } public int DateID { get; set; } public Nullable<int> ComparableTime { get; set; } public Nullable<int> OnlineDateID { get; set; } public Nullable<int> OnlineTime { get; set; } public Nullable<int> OfflineDateID { get; set; } public Nullable<int> OfflineTime { get; set; } public Nullable<byte> IsAvailable { get; set; } public short DataSourceID { get; set; } public byte OperationTypeID { get; set; } public byte ComparableTypeID { get; set; } public Nullable<short> PropertyTypeID { get; set; } public Nullable<long> LandParcelID { get; set; } public Nullable<long> BuildingID { get; set; } public Nullable<long> PropertyID { get; set; } public Nullable<long> GeographyID { get; set; } public Nullable<long> AddressID { get; set; } public Nullable<long> LocationID { get; set; } public Nullable<long> LAUID { get; set; } public Nullable<decimal> SurfaceArea { get; set; } public Nullable<byte> AreaTypeID { get; set; } public Nullable<byte> AreaMeasurementScaleID { get; set; } public Nullable<decimal> Price { get; set; } public Nullable<decimal> UnitPrice { get; set; } public Nullable<byte> PriceTypeID { get; set; } public byte PriceFrequencyID { get; set; } public byte PriceCurrencyID { get; set; } public bool isDeleted { get; set; } public string MD5 { get; set; } public System.DateTime CreationDatetime { get; set; } public Nullable<System.DateTime> LastUpdateDatetime { get; set; } public Nullable<System.DateTime> DeleteDatetime { get; set; } public int ExtractionBatchID { get; set; } public Nullable<long> ComparableParentID { get; set; } public Nullable<short> FloorLevelID { get; set; } public string Fraction { get; set; } public Nullable<short> UsePropertyTypeID { get; set; } public virtual D_Address D_Address { get; set; } public virtual D_AreaType D_AreaType { get; set; } public virtual D_ComparableType D_ComparableType { get; set; } public virtual D_Currency D_Currency { get; set; } public virtual D_DataSource D_DataSource { get; set; } public virtual D_Date D_Date { get; set; } public virtual D_FloorLevel D_FloorLevel { get; set; } public virtual D_Frequency D_Frequency { get; set; } public virtual D_Geography D_Geography { get; set; } public virtual D_Geography D_Geography1 { get; set; } public virtual D_LAU D_LAU { get; set; } public virtual D_Location D_Location { get; set; } public virtual D_MeasurementScale D_MeasurementScale { get; set; } public virtual D_OperationType D_OperationType { get; set; } public virtual D_PriceType D_PriceType { get; set; } public virtual D_PropertyType D_PropertyType { get; set; } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] public virtual ICollection<F_Comparable_Attribute> F_Comparable_Attribute { get; set; } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] public virtual ICollection<F_Comparable> F_Comparable1 { get; set; } public virtual F_Comparable F_Comparable2 { get; set; } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] public virtual ICollection<F_Comparable_Measure> F_Comparable_Measure { get; set; } }
We've searched the web trying to find a workaround but found nothing (at least working with a DB First EF model).
Is there any settings or change we can apply? Manual modifications are not an option as our model have more than 100 entities.
Thanks in advance,
Antonio
By convention the entity key property is Id. How do I modify my EntityType EDM registration to reflect my domain key (eg: builder.EntityType.HasKey(t => t.MyDomainKey)?
Implement extension method to represent IEnumerable to XElement similar to Community.OData.Linq.Json.ODataLinqExtensions.ToJson(...)
Hi Ihar,
I've been testing the filter inside the expand and for my use case i can't get it work. It seem that the $filter string is being bypased on nested entities.
In addition, when trying to use the .ToJson() seems that the "NullHandlingValue.Ignore" option is also being ignored
I've setup a .netfiddle for you to replicate those issues and point me in the right direction if i'm doing something wrong.
https://dotnetfiddle.net/KCbGib
Regards
I am using MongoDB.Driver
and trying to apply OData to the IMongoCollection<T>.AsQueryable()
var items = myCollection.Query().OData().Filter("((contains(Name,'2021')))").ToList();
But I am getting this exception
System.InvalidOperationException: 'The entity 'IncomingFileTransaction' does not have a key defined.'
I've tried adding both [Key]
and [BsonId]
to the class, but no luck
public abstract class AggregateRoot
{
[BsonId, Key]
public ObjectId Id { get; set; } = ObjectId.GenerateNewId();
public int ConcurrencyVersion { get; set; }
public DateTime CreatedUtc { get; set; } = DateTime.UtcNow;
public DateTime ModifiedUtc { get; set; } = DateTime.UtcNow;
}
public class IncomingFileTransaction : AggregateRoot
{
public string Name { get; set; }
}
Please tell me this is going to work with MongoDB.Driver!
Implement support of Parameter Aliases: http://docs.oasis-open.org/odata/odata/v4.0/errata03/os/complete/part2-url-conventions/odata-v4.0-errata03-os-part2-url-conventions-complete.html#_Toc453752356
sample filter: Param in (0,100)
throws exception:
"ExceptionType": "System.NotImplementedException",
"StackTrace": " w Microsoft.OData.UriParser.QueryNodeVisitor1.Visit(InNode nodeIn)\r\n w Microsoft.OData.UriParser.InNode.Accept[T](QueryNodeVisitor
1 visitor)\r\n w Community.OData.Linq.OData.Query.ParameterAliasNodeTranslator.Visit(ConvertNode nodeIn)\r\n w Microsoft.OData.UriParser.ConvertNode.Accept[T](QueryNodeVisitor1 visitor)\r\n w Community.OData.Linq.OData.Query.ParameterAliasNodeTranslator.Visit(BinaryOperatorNode nodeIn)\r\n w Microsoft.OData.UriParser.BinaryOperatorNode.Accept[T](QueryNodeVisitor
1 visitor)\r\n w Community.OData.Linq.OData.Query.ParameterAliasNodeTranslator.Visit(BinaryOperatorNode nodeIn)\r\n w Microsoft.OData.UriParser.BinaryOperatorNode.Accept[T](QueryNodeVisitor1 visitor)\r\n w Community.OData.Linq.OData.Query.ParameterAliasNodeTranslator.Visit(BinaryOperatorNode nodeIn)\r\n w Microsoft.OData.UriParser.BinaryOperatorNode.Accept[T](QueryNodeVisitor
1 visitor)\r\n w Community.OData.Linq.ODataLinqExtensions.Filter[T](ODataQuery`1 query, String filterText, String entitySetName)\r\n w AbcData.Services.News.DataModel.NewsODataService.GetNews(String filter) w
Is it possible to support the 'in' syntax to filter on multiple values at the same time. The following example shows the desired result: $filter=City in ('Paris', 'Berlin'). This should return to me all records in these cities. I tried to pass these to your backend without success: Unreadable query has been given Syntax error at position 15 in 'City in ('Paris', 'Berlin')'
Not all projects are using the default implementations of MS.Ext.DI.Abstractions which is MS.Ext.DI
For example, we're using Autofac.Extensions.DependencyInjection
TimeZoneInfoHelper
is an internal class without any means to influence it from outside the library, and it always returns the local timezone:
In our code we are using an OData filter expression like: SomeProperty ge 2014-01-01T00:00:00.0000000Z
, the right hand-side of which is represented as a DateTimeOffset
value under the hoods. The library processes that value by converting it to the local timezone and throwing away any timezone information like so:
I attempted to modify the source and specify DateTimeKind.Local
for the DateTime
value returned above, but that didn't bring about any change. The actual dataset in our case contains values for the relevant property with DateTimeKind.Utc
.
Hello,
we use this project since some weeks. It workds great ๐
No we encountered one issue.
Given is following architecture
class MyClassA
{
[Key]
public string String { get; set; }
public List<MyClassB> Subs { get; set; }
}
class MyClassB
{
[Key]
public int Integer { get; set; }
}
It looks like it is not possible to assign following odata:
$filter=String eq 'A'&expand=Subs($filter=Integer eq 1
Thanks in advance
Microsoft.AspNetCore.OData 8.0.0+ actually has no dependencies on WebAPI, which is one of the motivators of the project. (The naming, I presume, is just for legacy purposes).
That being said, the .OData()
wrapper in this repository is still super neat, as is a lot of the other helper code. It would just be nice to have a version that took that as a dependency instead of forking the whole OData codebase.
it works fine with filter startswith or eq
but with substringof i get
Microsoft.OData.ODataException: 'An unknown function with name 'substringof' was found. This may also be a function import or a key lookup on a navigation property, which is not allowed.'
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.