Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework Navigation Properties looping issue though WCF

I have a model like

public class User
{
    [Key]
    public long UserId { get; set; }

    [Required]
    public String Nickname { get; set; }

    public virtual ICollection<Group> Memberships { get; set; }
}

public class Group
{
    [Key]
    public long GroupId { get; set; }

    [Required]
    public String Name { get; set; }

    public virtual ICollection<User> Members { get; set; }
}

public class DataContext : DbContext
{
    public DbSet<User> Users { get; set; }
    public DbSet<Group> Groups { get; set; }

    public DataContext()
    {
        Configuration.LazyLoadingEnabled = true;
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>()
        .HasMany(u => u.Memberships)
        .WithMany(t => t.Members)
        .Map(x =>
        {
            x.MapLeftKey("UserId");
            x.MapRightKey("GroupId");
            x.ToTable("GroupMembers");
        });
    }
}

All goes fine when accessing the entities using a test console application, but I need to have this through a WCF service, here I got this exception:

Failed to invoke the service. Possible causes: The service is offline or inaccessible; the client-side configuration does not match the proxy; the existing proxy is invalid. Refer to the stack trace for more detail. You can try to recover by starting a new proxy, restoring to default configuration, or refreshing the service

The only way I found to have this working is, removing the navigator in one of the entities, because having the navigators in both sides causes a infinite looping.

Is there a way to have this working without removing the navigators?

like image 666
Micky Avatar asked Jul 30 '12 03:07

Micky


1 Answers

There are two issues if you try to use WCF:

  • First issue: Do you want to return related entities as well? Always turn off lazy loading when working with WCF / serialization and make sure that you manually use Include for relations you really want to return. Otherwise lazy loading will load all relation in the object graph. Moreover depending on the way how your service handles context's life cycle, the lazy loading can happen when the context is already disposed.
  • You must tell serializer about the circular reference or remove the circular reference. WCF by default uses DataContractSerializer. To remove the circular reference you can mark one of those navigation properties with IgnoreDataMember attribute or you can simply tell serializer about the circular reference by marking all entities with DataContract(IsReference = true) attribute and all member properties which should be serialized with DataMember attribute.
like image 177
Ladislav Mrnka Avatar answered Sep 24 '22 15:09

Ladislav Mrnka