IharYakimush / comminity-data-odata-linq

Use OData filter text query in linq expresson for any IQuerable without ASP.NET dependency. Support netstandard2.0
Other
42 stars 16 forks source link

Recursive loop of complex types #33

Open antoniosanchezgarcia opened 5 years ago

antoniosanchezgarcia commented 5 years ago

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 'DGeography1'. 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

IharYakimush commented 5 years ago

Hi Antonio,

I checked "StructuralTypeConfiguration" class and it looks like there is no settings which can help in this case. You have to avoid recursion.

Ihar

antoniosanchezgarcia commented 5 years ago

Hi Ihar,

First of all, thanks for your quick response. We really appreciate it.

Do you think that building a code first model would allow us to change complextype by entityset as described in this thread: https://stackoverflow.com/questions/21535114/odata-exception-a-recursive-loop-of-complex-types-is-not-allowed

Thanks in advance

IharYakimush commented 5 years ago

Hi Antonio,

I think you can try to do small POC before building full model.

FortuneN commented 2 years ago

What if i commented out this line

https://github.com/IharYakimush/comminity-data-odata-linq/blob/7a1e682d97ca9787e2a8f5b49979124d4e2d58ff/Community.Data.OData.Linq/Builder/StructuralTypeConfiguration.cs#L388

I'm guessing something bad will happen. What is it?