16

I'm have the strangest behavior with linq to entity / Json / MVC.net 4

I have this bit of code, and for some odd reason, every other list's property order is reversed.

var output = db.FooBar.Where(a => a.lookupFoo == bar)
                      .Select(a => new List<double>{
                                     //value's are the same per row 
                                     //for demonstration sake.
                          a.fooBarA,  //Always 12.34
                          a.fooBarB,  //Always 12.34
                          a.fooBarC,  //Always 0
                          a.fooBarD  //Always 0 //lazy casting to double from int
                      });
return Json(new {output});

output looks like so:

{
  "output": [
    [12.34, 12.34, 0,     0], 
    [0,     0,     12.34, 12.34], 
    [12.34, 12.34, 0,     0],
    [0,     0,     12.34, 12.34]
  ]
};

I've managed to work around it by putting a toList() between the Where, and Select, but I'd still like to know why this behavior is happening.

More info: EF 4.4 (tt generated Context), SQL Server 2008r2 express .NET 4.0, MVC 3.0, Vanilla System.Web.Mvc.JsonResult, table consists of a int primary key, floats for values excluding last one which is a int

jonni
  • 338
  • 1
  • 13
WillFM
  • 353
  • 1
  • 13
  • 2
    In your example, it's not order of objects that is flipped. Apparently values of properties on single object are switched(?). a.fooBarA holds value of a.fooBarC. Can you make example (or description) clear? – Nenad Feb 25 '13 at 21:05
  • I was assuming that (being there are no key's for the output) that that the actual properties were being switched not necessarily the values. P.S. Did you know your reputation is Evil(666) at the moment @Nenad – WillFM Feb 25 '13 at 21:21
  • 1
    Properties cannot be switched by Linq, so problem must be something else that is not obvious from your example. Evil, yes. That's why I stopped writing answers, only comments. :P – Nenad Feb 25 '13 at 22:32
  • Which json library are you using? Well, regardless, it's obviously something someone does that only gets exposed when lazy evaluation is performed. I suppose the only way to properly answer the question would be to set up symbols properly and step through the code until you figure it out... Alternatively there might be something else you're omitting - is it a vanilla EF setup or did you customize anything? I might give it a shot at reproducing it... – Alex Paven Feb 25 '13 at 23:18
  • 1
    Nope, can't reproduce using MVC4 and default Json serializer. – Alex Paven Feb 25 '13 at 23:50
  • I'll see if i can give a better (reproducable) example. Off the top of my head, I think its the built in Json Serializer though it may be json.net, will check when I get into work tomorrow, the project did start of as mvc.net 3.5, and was later switched to 4.0. And I'm using vanilla EF, with "database first" generated models. – WillFM Feb 26 '13 at 06:29
  • woops .net 4.0, and mvc 3.0 – WillFM Feb 26 '13 at 19:54
  • Have you verified that the data in the data source is correct? – William Feb 28 '13 at 19:17
  • @WillFM, The code in your sample isn't valid (i.e. no commas between the `a.fooBarX` items). Is it possible that something else was lost in the preparation of the question? – Simon MᶜKenzie Mar 04 '13 at 22:58
  • @William Yes, the data is correct. – WillFM Mar 11 '13 at 19:29
  • @Simon McKenzie, was writing pseudo code based on some production code that is privately maintained by my employer, missed out on the commas sorry about that. Only other things I left out is were using SQL Server 2008r2 Express. I haven't looked into this lately, but my next step will probably be to debug the SQL the EF generates and see if its happening in the query, or in EF Mapper. – WillFM Mar 11 '13 at 19:35
  • 1
    Seems like another outer variable trap http://stackoverflow.com/questions/3416758/outer-variable-trap – Onur May 24 '13 at 20:24
  • Unless your JSON library has a bug, it should *never* be rearranging the order of values in a JSON array. So either your JSON library is buggy (doubtful) or your claims about the values "Always" being some value are false. – Timothy Shields May 27 '13 at 01:02
  • 1
    To debug this further, what's the result if you change the `.Select` to `.Select(a => new List{1.0,2.0,3.0,4.0})`? – Mark Hurd Jun 01 '13 at 06:19
  • And similarly try `.Select(a => new List{a.fooBarA==12.34,a.fooBarB==12.34,a.fooBarC==0.0,a.fooBarD==0})`. – Mark Hurd Jun 01 '13 at 06:22
  • @Onur That could be a possibility, in which case, if I change my delegate to another name e.g. f instead of e, that might fix the issue, I've long since moved passed the issue (I use the toList method as mentioned in my answer, I was really just trying to clarify why this behavior happened otherwise). Next time I get the chance I'll look at the code, and see if making a new delegate will generate the expected behavior. – WillFM Jun 20 '13 at 18:49

2 Answers2

1

Try

var output = db.FooBar.Where(a => a.lookupFoo == bar)
                  .Select(a => new List<double>{
                                 //value's are the same per row 
                                 //for demonstration sake.
                      a.fooBarA,  //Always 12.34
                      a.fooBarB,  //Always 12.34
                      a.fooBarC,  //Always 0
                      a.fooBarD  //Always 0 //lazy casting to double from int
                  }).toList();
return Json(output);

On your way output just context the generated script for get data may be it Excute manytime in size Json()

Spudley
  • 166,037
  • 39
  • 233
  • 307
Kaiba Zax
  • 26
  • 3
0

Add a .ToArray and see what you get. Remember that the linq (Select.. exc) is only executed when IEnumerator is called.

I think if you add ToArray, the result would be the same each time, and consistent.

Hope that helps.

WhyMe
  • 535
  • 2
  • 13