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:
- Only few lookups actually used the ID, many used a GUID, which wasn't indexed
- 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
- 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
- var person = persons.List[personid].Value;
- var person = persons.List.Where(p => AsDynamic(p.Value).Name == "Daniel").Value;
- var all = AsDynamic(persons.List.Values);
- var all = AsDynamic(persons["Default"].List.Values);
- 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:
- var person = persons.List.First(p => p.EntityId == personid);
- var person = persons.List.Where(p => AsDynamic(p).Name == "Daniel");
- var all = AsDynamic(persons.List);
- var all = AsDynamic(persons["Default"]);
- var all = AsDynamic(persons["Default"]);
Additional Examples will follow
As people report various issues, I'll keep expanding this article.
Love from Switzerland,
Daniel