dotnet / dotnet/efcore

Consider supporting mapping HashSet (and other non-IList collections) as primitive collections

Open
#33,115 3 comments 23 reactions 0 assignees View on GitHub
area-primitive-collections customer-reported needs-design
Dominant language
C#
Stars
14.8k
Forks
3.4k
PR merge metrics
PR metrics pending

Description

Our primitive collections feature currently supports `IList` only, e.g. `HashSet` doesn't work for mapping a database primitive collection. Note that EF maps primitive collections to JSON arrays (or PG arrays in PG), but these aren't sets: they are ordered and allow duplicates. For example, that means that reading a JSON array would lose data (both duplicates and the ordering).

However, it may still make sense to allow users to map the JSON/PG array, as long as the user's code uses it as a set. That is, as long as it's understood that full roundtrippability isn't supported in this case, it would work.

Note that even if we don't support mapping database **columns** via HashSet, we may still choose to allow supporting parameterized HashSet; this seems particularly useful for Contains queries (`Where(b => someSet.Contains(b.Id))`).

Note that our value comparison would need to special-case sets when comparing two primitive collections; it would likely need to call [ISet.Equals](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.iset-1.setequals?view=net-7.0#system-collections-generic-iset-1-setequals(system-collections-generic-ienumerable((-0)))) if the type implements ISet (see similarity with https://xunit.net/docs/hash-sets-vs-linear-containers and https://github.com/xunit/xunit/issues/2831). However, SetEquals doesn't accept a comparer, but rather uses the comparer the set was initialized with; this would make it impossible to use the element value comparer configured in EF. We'd therefore likely need to duplicate the implementation of SetEquals in our own set comparer, etc.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.