SirZoro
SirZoro

Reputation: 151

Entity framework - Avoid circular Relationship in serialization

I have two tables : Users & Profiles. A user has one profile (1:1), a profile can be affected to many users, each profile has many modules, each module has many actions.

I'm sending this object from an asmx to a aspx page using a direct service call.

I got an error because of lazy loading ... so I disabled the lazy loading.

this.Configuration.LazyLoadingEnabled = false;

this works fine, I got my user, with the profile null.

To build the menu tree I have to retrieve the profile. I included It :

        User user = new User();
        using (cduContext db = new cduContext())
        {
            // get the user
            string encryptedPassword = Encryption.Encrypt(password);
            user = (from u in db.Users
                    where u.UserName.Equals(login) &&
                          u.Password.Equals(encryptedPassword)
                    select u).FirstOrDefault();
            // Include the users profile
            user = db.Users.Include("Profile").FirstOrDefault();
        }
        return user;

I got this error in the javascript call function :

A circular reference was detected while serializing an object of type 'CDU.Entities.Models.User'.

When I made a quick watch on the user object, in asmx ( before sending it ) , I found, that the profile has included the list of the users who had this pofile, each user has his profile loaded ... etc

Any idea please ?

Upvotes: 4

Views: 1182

Answers (1)

Erik Funkenbusch
Erik Funkenbusch

Reputation: 93444

Note, your code should look like this:

using (cduContext db = new cduContext())
{
    // get the user
    string encryptedPassword = Encryption.Encrypt(password);
    var user = from u in db.Users
               where u.UserName.Equals(login) &&
                     u.Password.Equals(encryptedPassword)
               select u;
    // Include the users profile
    return user.Include("Profile").FirstOrDefault();
}

In your code, you were throwing away the first query by overwriting it with the second. And there was no valid reason to create a blank user.

To address your problem, you're going to have make a decision on what you don't want to serialize. In your case, you probably don't want to serialize Profile.Users

You don't mention what serializer you're using. I'm assuming you're using the DataContract serializer?

EDIT:

You would mark your Profile.Users object with the [IgnoreDataMember] Attribute.

Upvotes: 3

Related Questions