0

I have migrated from Entity Framework 6 to EF Core and also Web Api .net framework to .net core.

I have many to many relationship that I have set up as follows

protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        var instrumentsToPlaces = modelBuilder.Entity<InstrumentPlace>();
        instrumentsToPlaces.ToTable("InstrumentsToPlaces");
        instrumentsToPlaces.HasKey(x => new { x.PlaceId, x.InstrumentId });

        instrumentsToPlaces.HasOne(i => i.Instrument)
            .WithMany(p => p.InstrumentsPlaces)
            .HasForeignKey(ip => ip.InstrumentId);

        instrumentsToPlaces.HasOne(p => p.Place)
            .WithMany(i => i.InstrumentsPlaces)
            .HasForeignKey(ip => ip.PlaceId);


        var instrumentsToStyle = modelBuilder.Entity<InstrumentStyle>();
        instrumentsToStyle.ToTable("InstrumentsToStyles");
        instrumentsToStyle.HasKey(x => new { x.StyleId, x.InstrumentId });

        instrumentsToStyle.HasOne(i => i.Instrument)
            .WithMany(s => s.InstrumentStyles)
            .HasForeignKey(si => si.InstrumentId);

        instrumentsToStyle.HasOne(s => s.Style)
            .WithMany(i => i.InstrumentStyles)
            .HasForeignKey(si => si.StyleId);

    }

I have included the navigation properties in the repository method as follows

        public Instrument GetInstrumentByName(string name)
    {
        using (var starsAndCatzDbContext = new StarsAndCatzDbContext())
        {
            var instrument = _starsAndCatzDbContext.Instruments
            .Include(a=>a.InstrumentsPlaces)
            .ThenInclude(a=>a.Place)
            .Include(a=>a.InstrumentStyles)
            .ThenInclude(a=>a.Style)
           .FirstOrDefault(i => i.Name == name);

           
            return instrument;

        }
       

    }

Here are the classes

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

    public  virtual ICollection<InstrumentPlace> InstrumentsPlaces { get; set; }
    public virtual ICollection<InstrumentStyle> InstrumentStyles { get; set; }
}

 public class InstrumentPlace
{
    public int InstrumentId { get; set; }
    public Instrument Instrument { get; set; }
    public int PlaceId { get; set; }
    public Place Place { get; set; }
}

     public class InstrumentStyle
{
    public int InstrumentId { get; set; }
    public Instrument Instrument { get; set; }
    public int StyleId { get; set; }
    public Style Style { get; set; }
}

    public class Style {
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<InstrumentStyle> InstrumentStyles { get; set; } 
}

        public class Place {
    public int Id { get; set; }
    public string Name { get; set; }
    public string Division { get; set; }
    public int Tier { get; set; }
    public string State { get; set; }
    public string Postcode { get; set; }
    public float? Latitude { get; set; }
    public float? Longitude { get; set; }
    public virtual ICollection<InstrumentPlace> InstrumentsPlaces { get; set; }
}

The WebAPI method to be called is

        [HttpGet("GetInstrumentByName/{suburb}/{instrument}"), Produces("application/json")]
    public Instrument GetInstrumentByName(string suburb, string instrument)
    {
        try
        {
            var result = _instrumentRepository.GetInstrumentByName(instrument);
            return result;
        }
        catch (Exception ex)
        {

            _logger.LogError(ex.Message);
            return new Instrument();
        }

    }

When I send the request to "/api/instruments/west-end/guitar" I get the expected result when I place a breakpoint before sending the response as follows

enter image description here

As you notice, the Navigation properties are loaded (when I expand the collections I can see all the properties being loaded as well). However the json response I receive is the following

enter image description here

Any suggestions or am I missing something here?

Thank you all in advanced

Community
  • 1
  • 1
carlosJ
  • 133
  • 2
  • 8
  • Can you post Instrument class definition please? – H. Herzl Dec 29 '16 at 05:59
  • 'public class Instrument { public int Id { get; set; } public string Name { get; set; } public List InstrumentsPlaces { get; set; } public List InstrumentStyles { get; set; } }' I had the collections as virtual ICollection before.. but changed it to see if that was the issue but nothing happened – carlosJ Dec 29 '16 at 06:00
  • 1
    I have a similar feature and I use public virtual Collection OrderDetails { get; set; } and I get the entity with navigation property, I think you need to check your serializer settings, have you checked? – H. Herzl Dec 29 '16 at 06:05
  • I haven't modified anything to the project, just the default settings. Can you point me to the right direction to the correct serializer settings? I also should mention that the EFcore is in separate library/project, and so is the WebAPI. I took this approach as I also need reference the models from other projects – carlosJ Dec 29 '16 at 06:11
  • In that case, please try to use public virtual Collection Name { get; set; } and let me know if that resolves your issue. Another thing I see on your code you're using scalar types instead of nullable types (e.g. int?) – H. Herzl Dec 29 '16 at 06:16
  • I have changed it back to public virtual Collection Name { get; set; } and it didn't solve the issue. In this case, it cannot be nullable as the ids are the primary and foreign keys – carlosJ Dec 29 '16 at 06:27
  • You need to post web api method code – H. Herzl Dec 29 '16 at 06:34
  • I have included the code, although it is also shown in the screenshot with the breakpoint – carlosJ Dec 29 '16 at 06:40

1 Answers1

1

Thanks @H. Herzl for giving me a hint.

The solution was found in this other question

services.AddMvc().AddJsonOptions(x => x.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);

https://stackoverflow.com/a/40501464/1513346

Community
  • 1
  • 1
carlosJ
  • 133
  • 2
  • 8