Question: why do you not allow `IImmutableList<T>` for collection navigational properties with backing fields?
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 25/100
Research direction
Start with the failing test TestSaveBookOneReviewAndReadOk in Test/UnitTests/TestDataLayer/Ch08_RelationshipBackingFields.cs at line 151. Read the relationship backing-field behavior and the RelationshipsSnapshot stack trace to determine why a HashSet is cast to IImmutableList. This issue is a question rather than a defined change, so a maintainer would need to clarify the expected behavior before implementation.
Written by the indexing model from the issue text.
Description
This is a question, rather than a request for a change!
I want to create entity classes where no properties can be changed outside the class (DDD-styled class). For instance:
public class Book
{
private readonly List<Review> _reviews;
public IEnumerable<Review> Reviews => _reviews.ToList();
//... other properties left out
}
From my testing I know that collection navigational properties can use the following types -
IEnumerable<T>IReadOnlyCollection<T>
I want to move away from using IEnumerable<T>, as it has (small) performance problems when you call it multiple times. I would like to use IImmutableList<T> as that sounds like a better type because it ensures that a) it takes a copy (AsReadOnly doesn't take a copy) and, b) makes parallel operations work better. But I get I use IImmutableList<T>.
TestSaveBookOneReviewAndReadOk [0:00.749] Failed: System.InvalidCastException : Unable to cast object of type 'System.Collections.Generic.HashSet`1[DataLayer.EfClasses.Review]' to type 'System.Collections.Immutable.IImmutableList`1[DataLayer.EfClasses.Review]'.
System.InvalidCastException : Unable to cast object of type 'System.Collections.Generic.HashSet`1[DataLayer.EfClasses.Review]' to type 'System.Collections.Immutable.IImmutableList`1[DataLayer.EfClasses.Review]'.
at lambda_method(Closure , InternalEntityEntry )
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.RelationshipsSnapshot..ctor(InternalEntityEntry entry)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.EnsureRelationshipSnapshot()
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntrySubscriber.SnapshotAndSubscribe(InternalEntityEntry entry)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.StartTracking(InternalEntityEntry entry)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.SetEntityState(EntityState oldState, EntityState newState, Boolean acceptChanges, Boolean modifyProperties)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.SetEntityState(EntityState entityState, Boolean acceptChanges, Boolean modifyProperties, Nullable`1 forceStateWhenUnknownKey)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityGraphAttacher.PaintAction(EntityEntryGraphNode`1 node)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityEntryGraphIterator.TraverseGraph[TState](EntityEntryGraphNode`1 node, Func`2 handleNode)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityGraphAttacher.AttachGraph(InternalEntityEntry rootEntry, EntityState targetState, EntityState storeGeneratedWithKeySetTargetState, Boolean forceStateWhenUnknownKey)
at Microsoft.EntityFrameworkCore.DbContext.SetEntityState(InternalEntityEntry entry, EntityState entityState)
at Microsoft.EntityFrameworkCore.DbContext.SetEntityState[TEntity](TEntity entity, EntityState entityState)
at Microsoft.EntityFrameworkCore.DbContext.Add[TEntity](TEntity entity)
at Test.UnitTests.TestDataLayer.Ch08_RelationshipBackingFields.TestSaveBookOneReviewAndReadOk() in C:\Users\JonPSmith\source\repos\EfCoreinAction-SecondEdition\Test\UnitTests\TestDataLayer\Ch08_RelationshipBackingFields.cs:line 151
IImmutableList<T> seems to tick all the boxes by supporting IEnumerable<T>, ICollection<T>, IList<T>. Also AsReadOnly() doesn't work with a HashSet, but ToImmutableList() does. so why does EF Core not support it? Is there something fundamental or just the way it is written?
NOTE: I have tried this on EF Core 3.1 and 5-preview4
- Dominant language
- C#
- Stars
- 14.8k
- Forks
- 3.4k
- Avg merge
- 2d 5h
- Merged PRs (30d)
- 134
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from dotnet/efcore
-
Difficulty 4/5 3-5 days Newbie friendliness 55/100
-
customer-reported
Difficulty 5/5 Over a week Newbie friendliness 38/100
-
area-cosmos area-vector-search
Difficulty 5/5 Over a week Newbie friendliness 25/100
-
area-cosmos
Difficulty 5/5 Over a week Newbie friendliness 25/100
-
area-tools needs-design
Difficulty 4/5 3-5 days Newbie friendliness 25/100
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
-
:watch: Not Triaged 11.0 fundamentals/subsvc
Difficulty 2/5 1-3 hours Newbie friendliness 92/100
dotnet/AspNetCore.Docs#37699 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
SubtitleEdit/subtitleedit#15108 · 1 comment ·
-
area/docs-content Bug pulumi/docs
Difficulty 1/5 1-3 hours Newbie friendliness 94/100
-
agentic-workflows untriaged
Difficulty 2/5 1-3 hours Newbie friendliness 76/100