开发者

how to json seralize entity framework many to many relationships without circular reference

I have 3 tables in my database - Conference, ActivityTypes and a joining table ConferenceActivities. Each conference may have a zero or many standard activities and each activity may occur in zero or more conferences.

Conference (ConferenceID, ConferenceName)

ConferenceActivities (ConferenceID,ActivityTypeID)

开发者_JS百科ActivityTypes (ActivityTypeID, ActivityTypeDesc)

I used Entity framework over my existing database, with the .tt templates in a MVC3 app I generated a DbContext and the POCO objects, noting that it generates just two objects, ActivityType and Conference which is nice it seems to understand the intermediary table.

It also adds a collection of activities to my conference

 public virtual ICollection<ActivityType> ActivityTypes { get; set; }

And a collection of Conferences to my Activity.

public virtual ICollection<Conference> Conferences { get; set; }

I would like to return using JSON an object matching a specific conference.. that includes the ActivityTypes. Some might described this object as 'shaped' or 'jagged' because it has a collection within it.

I'm using code like the following although I've tried many different variations incase I had the syntax wrong but I still get a runtime error about recursion.

public JsonResult GetConference(int conferenceId)
{
    Conference x = context.Conferences.Include("ActivityTypes").FirstOrDefault<Conference>(i => i.EventID == eventId);
    return Json(x, JsonRequestBehavior.AllowGet);
}

It doesn't seem to work 'out of the box' and I see a lot of Stack Overflow questions that seem to relate but despite trying numerous different approaches but all create an error about recursion or parameterless constructors.. I am starting to doubt whether this is even possible.

I have tried attaching [IgnoreDataMemberAttribute] or [ScriptIgnore] to different properties to stop it trying to serialise the recursive relationship (I think the form is irrelevant but when your desperate..) and I still get the same error.

I've tried this sort of approach which generates the parameterless error

    var thing = from r in context.Conferences
                select new
                {
                    r.ConferenceID,
                    r.ConferenceName,
                    ActivityTypes = new List<ActivityType>(
                        (from c in r.ActivityTypes
                         select new ActivityType()
                         {
                             ActivityTypeDesc = c.ActivityTypeDesc,
                             ActivityTypeID = c.ActivityTypeID
                         }).Cast<ActivityType>())
                };
     return Json(thing, JsonRequestBehavior.AllowGet);

Another suggestion was to set the Lazy Loading Enabled property on the model to false.. which made no difference I still get the recursion error.

I've tried removing the Virtual keyword which I belive turns off the lazy loading.. and trying with .Include(..) but again no joy.

Another suggestion was to change the accessor from public to internal however that made no different to the serialization.

Somebody also suggested removing the collection of Conferences from the ActivityType class, not really what I want to do.. but doing that just produces an error `Schema specified is not valid.' anyway.

I am using I believe the latest version nuget and the associated EF, scaffolding and templates.

Is what I'm trying to achieve something that should work out of the box? If so what setting(s) could I be missing and if not, what is the best practise here - the only way I know I can make this work is to build up the object manually myself.

Suggestions or a link to a complete working demo (I've seen a lot of suggestions and code snippets that just don't seem to work!!) appreciated. I'm certain somebody's done this and got it working surely.


don't pass your model classes around. create a viewmodel with the data you need for the view, or, in your case, the json output. i see where you tried projecting it into an anonymous type, but project it into a concrete viewmodel and it should work perfectly.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜