问题描述:

I'm running into an issue while attempting to return recursive serialized objects generated by Entity Framework 6 through a Web API. Here's a small example of my problem:

[Serializable]

[DataContract]

public partial class Thing

{

public Thing()

{

this.OtherThings = new HashSet<OtherThings>();

}

[DataMember]

public int ThingId { get; set; }

[DataMember]

public string ThingName { get; set; }

//Not included in serialization

public virtual ICollection<OtherThing> OtherThings { get; set; }

}

[Serializable]

[DataContract]

public partial class OtherThing

{

public OtherThing()

{

this.Things = new HashSet<Things>();

}

//I want these

[DataMember]

public int OtherThingId { get; set; }

[DataMember]

public string OtherThingName { get; set; }

//Do NOT want this from GetAllThings() to avoid circular references

public virtual ICollection<Things> Things { get; set; }

}

The decorators are generated from the Context.tt file, and there are a lot more properties in my real object, making hand-editing each of these impossible - not to mention the files are auto-generated.

I retrieve the collection of Things from my database with this simple method:

public static class Repo {

internal static IQueryable<Thing> GetAllThings()

{

//Context is an initialized database context

return Context.Things;

}

}

Which returns the entire collection of Things, which contain OtherThings, which each contain more Things. The problem becomes obvious when I try to serialize this as a Web API response:

public class API {

//This response is serialized to JSON

public List<Thing> GetAllThings()

{

var things = Repo.GetAllThings();

//Do something here to exclude

return things.ToList();

}

}

Naturally, the serializer will fail (or overflow), because there are circular references. Normally I would add [DataIgnore] to the offending properties and just forget about DataContracts altogether, but if I request a collection of Things, I just want each connected OtherThing, and vice-versa.

Can this be done?

网友答案:

Assuming that Context.Things is of type DbSet you can use

return Context.Things.Select(s => s).Include(s => s.OtherThings);
相关阅读:
Top