score:0

Does this still need answering?

As you already found out, F# anonymous types order fields by name (not by source code order of declaration, as C# anonymous types would do).

When writing {| B = c.CategoryID; A = c.CategoryName; |} in a LINQ query, this will not actually pass an anonymous type, rather the compiler creates an System.Linq.Expressions.Expression that describes how to construct the anonymous type, and later on the underlying framework implementing LINQ (e.g., the Entity Framework) will try to parse that expression (and create e.g. SQL code from it).

Problem here is, c.CategoryID and c.CategoryName may have side effects, hence the compiler will evaluate them in the order specified in the source code (first ID, then Name), but assign them in the order of the anonymous type.

Long story short, the generated System.Linq.Expressions.Expression first will evaluate c.CategoryID, assign the value to a temporary variable, evaluate c.CategoryName, assign that to the anonymous type's first field, and finally assign the temporary variable to the anonymous type's second field. And the EF translator later on does not know how to handle the temporary variable (e.g., how to translate that to SQL.)

(In C#, no field reordering happens, so no temporary variables are required to mask side effects, so the expression parser will not face that problem.) (The F# anonymous type at present is not fully fit for LINQ.)


Related Articles