Tony,

With once again a cursory glance.

Not sure it looks like it should work....  the pattern we are following is:

ObjectContext dbContext = ((IObjectContextAdapter)db).ObjectContext;

var set = dbContext.CreateObjectSet<TimesheetItem>();

set.MergeOption = MergeOption.NoTracking

and then building the query after that.....

Neil.

On 27 September 2012 13:50, Tony Wright <tonyw...@gmail.com> wrote:
> Thanks Michael and Neil.
>
> Michael, I understand your point about ensuring that only the required data
> is returned to the client, however in this case I am happy for the lot to be
> returned.
>
> It seems like a bit of a hack to go through and detach every object. In
> fact, I probably wouldn't recommend that to anyone, although I'm sure it has
> its use!
>
> I went to the EF5 designer, right clicked, properties, then set the property
> Lazy Loading Enabled to false, and it now works without needing a separate
> POCO object. I don't know how happy I am about that, though, as I lose the
> benefits of lazy loading!
>
> So I thought I'd have a go at the MergeOption.Notracking version.
>
> It wouldn't let me cast my query to an ObjectQuery, because my EF database
> context is a DbContext.
>
> So I cast it:
>             ObjectContext dbContext =
> ((IObjectContextAdapter)db).ObjectContext;
>
>             var set = dbContext.CreateObjectSet<TimesheetItem>();
>
>             var result = from ti in set
>                          where ti.StaffId == staffId && ti.TimesheetPeriodId
> == timesheetPeriodId
>                          orderby ti.StartTime, ti.ForDate
>                          select ti;
>
>             ObjectQuery<TimesheetItem> query =
> (ObjectQuery<TimesheetItem>)result;
>
>             var queryResult = query.Execute(MergeOption.NoTracking);
>
>             List<TimesheetItem> listOfTimesheetItems = queryResult.ToList();
>             return Json(new { TimesheetItems = listOfTimesheetItems });
>
> Unfortunately, that doesn't work either. All referenced objects are lazy
> loaded. Hmmm.
>
> Is there something I'm missing here?
>
> T.
>
>
> -----Original Message-----
> From: ozdotnet-boun...@ozdotnet.com [mailto:ozdotnet-boun...@ozdotnet.com]
> On Behalf Of Neil Young
> Sent: Thursday, 27 September 2012 11:45 AM
> To: ozDotNet
> Subject: Re: JSON issue MVC4.5, EF5
>
> Without lookig very hard I would suggest that Lazy Loading is not your
> friend here and the serialization is walking your object graph and failing.
>
> Few  options you can run with query with:
> 1.  a MergeOption of NoTracking
> (http://blogs.msdn.com/b/dsimmons/archive/2010/01/12/ef-merge-options-and-co
> mpiled-queries.aspx)
> 2. or you can turn lazy loading off
> m_objectContext.ContextOptions.LazyLoadingEnabled
> 3. Or you can simply detach the object before returning it (but if you have
> any releated objects then detach will simply remove them from your object so
> they won't travel down in the serialisation).
>
> Either way you are going to need to make sure that everything you want has
> already been loaded ie any related objects- either with a strategy at query
> time or by explicitly loading those sub tables.
>
> Hope that helps.
>
> Neil.
>
> On 27 September 2012 10:30, Tony Wright <tonyw...@gmail.com> wrote:
>> Hi all,
>>
>>
>>
>> Can someone please tell me the problem with using EF5 generated model
>> classes when passing data using JSON calls?
>>
>>
>>
>> If I call an EF query and retrieve some EF generated classes with
>> references to other classes, then if I try to pass them directly back
>> to the view via a JSON call, they fail.
>>
>>
>>
>> If I retrieve the classes via the EF query, populate my own stripped
>> down
>> (POCO) classes, and pass my stripped down classes back to the view via
>> a JSON call, they succeed.
>>
>>
>>
>> Is there a trick to using the EF classes all the way through, or is
>> this supposed to be a bad practice and I am supposed to create POCO
>> classes every time?
>>
>>
>>
>> Regards,
>>
>> Tony
>>
>>
>>
>>
>>
>> Example code. The first is a Go button that I click that passes a
>> staffId and a timesheetPeriodId to the controller. It is meant to
>> return a subset of timesheet items.
>>
>>
>>
>> <script src="/Scripts/jquery-1.7.1.min.js"
>> type="text/javascript"></script>
>>
>> <script>
>>
>>     $(function () {
>>
>>         $('#GoButton').click(function () {
>>
>>             var url = '@Url.Action("LoadNewTimesheet", "Timesheet")';
>>
>>             $.post(url, { staffId: $('#staff').val(), timesheetPeriodId:
>> $('#period').val() },
>>
>>                     function(data) {
>>
>>                         viewModel.LoadTimesheetComplete(data);
>>
>>                     });
>>
>>
>>
>>         }
>>
>>     )
>>
>>     });
>>
>> </script>
>>
>>
>>
>> Here is the controller code that works. It basically retrieves the
>> timesheet items from the database, populates poco classes, then passes
>> the poco classes back to the view.
>>
>>
>>
>>         [HttpPost]
>>
>>         public ActionResult LoadNewTimesheet(int staffId, int
>> timesheetPeriodId)
>>
>>         {
>>
>>             List<JsonTimesheetItem> listOfTimesheetItems = new
>> List<JsonTimesheetItem>();
>>
>>
>>
>>             List<TimesheetItem> returnedList =
>> db.TimesheetItem.Where(ti => ti.StaffId == staffId &&
>> ti.TimesheetPeriodId == timesheetPeriodId)
>>
>>                                   .OrderBy(ti =>
>> ti.StartTime).OrderBy(ti => ti.ForDate).ToList();
>>
>>
>>
>>             foreach (TimesheetItem ti in returnedList)
>>
>>             {
>>
>>                 listOfTimesheetItems.Add(new JsonTimesheetItem()
>>
>>                 {
>>
>>                     TimesheetItemId = ti.TimesheetItemId,
>>
>>                     TimesheetPeriodId = ti.TimesheetPeriodId,
>>
>>                     ForDate = ti.ForDate,
>>
>>                     TaskId = ti.TaskId,
>>
>>                     StartTime = ti.StartTime,
>>
>>                     EndTime = ti.EndTime,
>>
>>                     NonWorkTime = ti.NonWorkTime,
>>
>>                     AdditionalNotes = ti.AdditionalNotes,
>>
>>                     IsLocked = ti.IsLocked,
>>
>>                     ApprovalStatusId = ti.ApprovalStatusId,
>>
>>                     Hours = ti.Hours,
>>
>>                     ImportTaskName = ti.ImportTaskName,
>>
>>                     StaffId = ti.StaffId,
>>
>>                     IsDailyRate = ti.IsDailyRate
>>
>>                 });
>>
>>             }
>>
>>
>>
>>             return Json(new { TimesheetItems = listOfTimesheetItems
>> });
>>
>>         }
>>
>>
>>
>> On the other hand, the following fails when populated, I think because
>> other classes referenced within the TimesheetItem class somehow screw
>> up JSON, and the success function in javascript never gets called.
>>
>>
>>
>>         [HttpPost]
>>
>>         public ActionResult LoadNewTimesheet(int staffId, int
>> timesheetPeriodId)
>>
>>         {
>>
>>             List<TimesheetItem> returnedList =
>> db.TimesheetItem.Where(ti => ti.StaffId == staffId &&
>> ti.TimesheetPeriodId == timesheetPeriodId)
>>
>>                                   .OrderBy(ti =>
>> ti.StartTime).OrderBy(ti => ti.ForDate).ToList();
>>
>>
>>
>>             return Json(new { TimesheetItems = returnedList });
>>
>>         }
>>
>>
>>
>> Do I have to create POCO classes every time? Apart from what I see as
>> an unnecessary extra layer of processing, maintenance and (small)
>> performance hit, I find them annoying!
>>
>>
>>
>>
>

Reply via email to