Efcore: Self referencing loop error

Created on 16 Feb 2018  Â·  8Comments  Â·  Source: dotnet/efcore

Hey guys, I found an issue with JSON, Razor Pages (Core 2) and EF (Core 2). I know all about self referencing loops and usually it can be solved with configuration. I added configuration and it did not work, I am still getting the error. Below you can see my configuration in "Startup.cs":

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {

            services.AddMvc().AddJsonOptions(options =>
            {
                options.SerializerSettings.ContractResolver = new Newtonsoft.Json.Serialization.DefaultContractResolver();
                options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Serialize;
                options.SerializerSettings.PreserveReferencesHandling = PreserveReferencesHandling.Objects;
            });

            services.AddDbContext<CapitalMarketsRMBSContext>(options =>
                options.UseSqlServer(Configuration.GetConnectionString("CapitalMarketsRMBSContext")));

            //services.AddDbContext<CapitalMarketsReportsContext>(options =>
            //    options.UseSqlServer(Configuration.GetConnectionString("CapitalMarketsReportsContext")));

        }

and when I make this simple call, I get the error:

      public void OnGet()
        {
            Pool = _context.Rmbspool.Include(p => p.RmbsCertificateRates).First();
        }

Here are both entities involved in the call:

    public partial class RmbsPool: EntityBase
    {
        //*** Omitted other properties for clarity ***

                /// <summary>
        /// Child RmbsCertificateRates where [RMBSCertificateRate].[PoolId] point to this entity (FK_RMBSCertificateRate_RMBSPool)
        /// </summary>
        public virtual System.Collections.Generic.ICollection<RmbsCertificateRate> RmbsCertificateRates { get; set; } // RMBSCertificateRate.FK_RMBSCertificateRate_RMBSPool

    }

And the "Many" class:

 [Serializable]  
public partial class RmbsCertificateRate: EntityBase
    {
        //*** Omitted other properties for clarity ***
               [Required]
        [Display(Name = "Pool ID")]
        public int PoolId
        {
            get { return _poolId; }
            set { SetProperty(ref _poolId, value); }
        }

        /// <summary>
        /// Parent RmbsPool pointed by [RMBSCertificateRate].([PoolId]) FK_RMBSCertificateRate_RMBSPool)
        /// </summary>
        public virtual RmbsPool RmbsPool { get; set; } // FK_RMBSCertificateRate_RMBSPool
    }
closed-question

Most helpful comment

I tried ignore, and it didn't work

All 8 comments

Can you explain here the error you see?

An unhandled exception occurred while processing the request.

JsonSerializationException: Self referencing loop detected with type 'System.Collections.Generic.List`1[RMBSWeb.Main.Models.RmbsCertificateRate]'. Path 'data[0].RmbsPool'.
Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.CheckForCircularReference(JsonWriter writer, object value, JsonProperty property, JsonContract contract, JsonContainerContract containerContract, JsonProperty containerProperty)

This does not sound like error from EF Core. But I can be wrong.
Unless you have no information in your table. and the error message is not what you want.
Try swapping First() for FirstOrDefault()

I can see the data load into the variable "Pool", but I guess when it is sending it back to the client via JSON, thats when it occurs.

If you can see the data load ... the wonderful EF Core did its part ✅

Can you attach a project to reproduce this error here?
So I could try to play, and some member of the team too.

      services.AddMvc().AddJsonOptions(options =>
            {
                options.SerializerSettings.ContractResolver = new Newtonsoft.Json.Serialization.DefaultContractResolver();
                options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Serialize;
                options.SerializerSettings.PreserveReferencesHandling = PreserveReferencesHandling.Objects;
            });

This is incorrect
ReferenceLoopHandling should be set to ignore and not serialize. See https://github.com/aspnet/EntityFrameworkCore/issues/4646#issuecomment-189152043

I tried ignore, and it didn't work

Was this page helpful?
0 / 5 - 0 ratings