Recursion in the Entity-framework

Asked

Viewed 275 times

1

I’m starting in c# and I’m having some difficulties with Entity-Framework. I have the following scenario:

public InstituicaoMap()
{
    // Primary Key
    HasKey(t => t.IdInstituicao);

    // Properties
    Property(t => t.Nome)
    .IsRequired()
    .HasMaxLength(255);
}

public CampanhaMap()
{
    // Primary Key
    this.HasKey(t => t.IdCampanha);

    // Properties
    this.Property(t => t.Texto)
        .IsRequired()
        .HasMaxLength(160);

    this.Property(t => t.DataEdicao)
        .IsFixedLength()
        .HasMaxLength(8)
        .IsRowVersion();

    // Relationships
    this.HasRequired(t => t.Instituicao)
        .WithMany(t => t.Campanhas)
        .HasForeignKey(d => d.IdInstituicao);
}

I am implementing a campaign CRUD, and at the moment I am working on the method "IEnumerable<Campanha> List()" (listing all registered campaigns).

Apparently it is working. For every campaign returned in the "list" there is an Institution object inside. ae all right. The problem is that within the institution there is a list of campaigns, that there are institutions, that there is another list of campaigns... and so it goes.

1 - I am concerned about the memory consumption and/or some problem that this recursion may cause.

2 - I am sending this return to View via JSON (as grid paging will be done with AJAX/JSON).

return new ContentResult
{
    Content = JsonConvert.SerializeObject(v),
    ContentType = "application/json"
};

In this return, I am getting an "infinite looping" error from Jsonconvert. In fact, because the campaigns object is recursive.

What can I do?

  • Your question sounds a lot like a question I asked here:http://answall.com/questions/35109/serialize-objects-para-json-a-circular-reference-was-detected-while-s

2 answers

5


You can use the annotation in your list, or map to ignore, in your configuration. The first mode is simpler, just do this:

[JsonIgnore]
public virtual Instituicao Instituicao{get;set;}

The second way, it would look like this yours CampanhaMap:

public CampanhaMap()
{
    // Primary Key
    this.HasKey(t => t.IdCampanha);

    // Properties
    this.Property(t => t.Texto)
        .IsRequired()
        .HasMaxLength(160);

    this.Property(t => t.DataEdicao)
        .IsFixedLength()
        .HasMaxLength(8)
        .IsRowVersion();

    // Relationships
    this.HasRequired(t => t.Instituicao)
        .WithMany(t => t.Campanhas)
        .HasForeignKey(d => d.IdInstituicao);

    this.Ignore(t => t.Instituicao);

}

Or, if not that, it might disable the Leazy Loading EF in its context. Something like this:

  public YouContext(): base("name=SchoolDBEntities")
    {
        this.Configuration.LazyLoadingEnabled = false;
    }
  • there is still a third option, to inform JSON.NET that the Institution and Campaign type are references, this can be done by placing the attribute [JsonObject(IsReference = true)] or [DataContract(IsReference = true)] in the classes, or using the option PreserveReferencesHandling = PreserveReferencesHandling.Objects, but in his case, because it’s a relationship n:n, this may generate a huge JSON object.

-1

Another way would be for you to create your own class for your needs.

Using the Automapper in your project and not using EF classes for display and return.

There’s a story about Eduardo Pires talking about SOLID .

I advise you not to use Lazy Loading as it makes separate queries at the base. Vandagem is that when you need the data just call the property that the query is done automatically.

Advice to use Eager Loading where you tell EF what you need to load.

I killed myself a lot with EF6 is not easy is very confusing and does not have many materials on. I advise to see these sites...

http://www.eduardopires.net.br/? s=solid&submit=Search

http://www.entityframeworktutorial.net/

Browser other questions tagged

You are not signed in. Login or sign up in order to post.