Skip to main content
Home  ›  Blog

Fixing the Breaking Change in 2sxc 9.8 (List instead of Dictionary)

2sxc 9.8 had to introduce a breaking change to allow for a wide range of features. This changed something fairly hidden - but if you're affected, here's how to fix it. 

Change: List of Items Instead of Dictionary of Items

What was changed was very simple: DataSource objects have a property called List, which delivers the items of this data-source. This List object was actually not a list, but a dictionary of type Dictionary<int, IEntity>. 

The original reasoning behind it was that it would be faster to find an entity by number if we have this kind of access, but it turned out to be a bad decision, for the following reasons:

  1. Only few lookups actually used the ID, many used a GUID, which wasn't indexed
  2. If we generated new items (like from a CSV DataSource), they would often not have a number-ID, which forced us to generate fake IDs, introducing new problems
  3. If we combined data from many sources, the chance that an ID was already used (let's say the item 27 and the user 27) was very high, and this made it impossible to combine such lists. 

Because we really want to open up the EAV / 2sxc to any kind of data, we had to get rid of this Number-Id is a unique property problem...

So we changed the List-property to be an IEnumerable<IEntity>.

We're really sorry to introduce breaking changes - but this was extremely important to going forwards. No further breaking changes are expected in the near future. 

Side Effects and Fixing Them

In 99% of all cases, nobody noticed the change, because usually the commands used in a Razor-template would not actually use the List-property. But there are exceptions, like this:

Some (mostly older) demo code used the List to lookup an item, resulting in code a bit like this

  1. var person = persons.List[personid].Value;
  2. var person = persons.List.Where(p => AsDynamic(p.Value).Name == "Daniel").Value;
  3. var all = AsDynamic(persons.List.Values);
  4. var all = AsDynamic(persons["Default"].List.Values);
  5. var all = AsDynamic(persons["Default"].List.Select(p => p.Value));

In these situations, the ".Value" or ".Values" is the problem, because it doesn't exist any more. It's actually not needed - the above examples would be rewritten as:

  1. var person = persons.List.First(p => p.EntityId == personid);
  2. var person = persons.List.Where(p => AsDynamic(p).Name == "Daniel");
  3. var all = AsDynamic(persons.List);
  4. var all = AsDynamic(persons["Default"]);
  5. var all = AsDynamic(persons["Default"]);

Additional Examples will follow

As people report various issues, I'll keep expanding this article.

Love from Switzerland,

Daniel Mettler grew up in the jungles of Indonesia and is founder and CEO of 2sic internet solutions in Switzerland and Liechtenstein, an 20-head web specialist with over 800 DNN projects since 1999. He is also chief architect of 2sxc (see github), an open source module for creating attractive content and DNN Apps.

Read more posts by Daniel Mettler