-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cosmos: Add basic support for collections and dictionaries of primitive types #25344
Conversation
Hello @AndriySvyryd! Because this pull request has the p.s. you can customize the way I help with merging this pull request, such as holding this pull request until a specific person approves. Simply @mention me (
|
Apologies, while this PR appears ready to be merged, I've been configured to only merge when all checks have explicitly passed. The following integrations have not reported any progress on their checks and are blocking auto-merge:
These integrations are possibly never going to report a check, and unblocking auto-merge likely requires a human being to update my configuration to exempt these integrations from requiring a passing check. Give feedback on thisFrom the bot dev teamWe've tried to tune the bot such that it posts a comment like this only when auto-merge is blocked for exceptional, non-intuitive reasons. When the bot's auto-merge capability is properly configured, auto-merge should operate as you would intuitively expect and you should not see any spurious comments. Please reach out to us at fabricbotservices@microsoft.com to provide feedback if you believe you're seeing this comment appear spuriously. Please note that we usually are unable to update your bot configuration on your team's behalf, but we're happy to help you identify your bot admin. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great, and nice to see some Npgsql code helping out :)
General comments:
- Nested collections (e.g. arrays over array). We should consider doing this now if it's relatively trivial, since seems pretty high-value.
- Value converters, i.e. whatever converters the built-in ValueConverterSelector provides, Cosmos should also provide converters for collections over those primitive types. Npgsql provides this, we could maybe even add this to the core ValueConverterSelector. Should definitely be out of scope for 6.0.
|
||
if (clrType.IsArray) | ||
{ | ||
var elementMapping = FindPrimitiveMapping(new TypeMappingInfo(elementType)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is the question of arrays over arrays, arrays over dictionaries over arrays, etc. I'm assuming this is all supported as we're in JSON, right? If so, this should recurse into FindMapping (and we should probably add tests too).
We could also define this as advanced/out-of-scope, in case this is complex to do.
One more thought - there's also the .NET immutable collection types (e.g. ImmutableDictionary), which could be a great match efficient collection change tracking: you can do relatively efficient non-destructive mutation (getting back a new instance), and then you have to assign that instance back (so the comparer can just check reference equality). Npgsql partially supports (npgsql/efcore.pg#1491). |
Yes, and I added a test for it. We don't snapshot it when it's mapped as |
|
Is there any provided examples to this new functionality, or could someone provide some? |
OK. At the time, when implementing support for ImmutableDictionary, I made a different decision:
In other words, it may be OK for a comparer to return false even for structurally-equal instances, assuming the only downside is a superfluous update that could have been avoided (i.e. assuming it's purely a perf question, structurally comparing for non-equal references slows down the common case in order to benefit the rare case). Am making a note in #25364 to think about this if/when we move the collection comparers to core. |
There isn't much to show, just add an array, |
I've tried this already, and it seems to be ignoring the Array that I parsed in the Dbset. I've also tried with Lists, but it comes to the same conclusion. Likewise, I think it's because I'm using the 5.0.8 version Nuget package that doesn't seem to have that update due to how recent it is. |
Yes, it was merged 3 days ago, it's only available in the latest daily build |
I'm using version Is there a specific version in which we should expect this feature? |
6.0.0-rc1 |
Is this really closed? I am using EF Core 6.0, a sample could be found here, and I am getting the following error 🤔 Unhandled exception. System.InvalidOperationException: The property 'Book.Tags' is of type 'IReadOnlyCollection<string>' which is not supported by the current database provider. Either change the property CLR type, or ignore the property using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.
at Microsoft.EntityFrameworkCore.Infrastructure.ModelValidator.ValidatePropertyMapping(IModel model, IDiagnosticsLogger`1 logger)
at Microsoft.EntityFrameworkCore.Infrastructure.ModelValidator.Validate(IModel model, IDiagnosticsLogger`1 logger)
at Microsoft.EntityFrameworkCore.Cosmos.Infrastructure.Internal.CosmosModelValidator.Validate(IModel model, IDiagnosticsLogger`1 logger)
at Microsoft.EntityFrameworkCore.Infrastructure.ModelRuntimeInitializer.Initialize(IModel model, Boolean designTime, IDiagnosticsLogger`1 validationLogger)
at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.GetModel(DbContext context, ModelCreationDependencies modelCreationDependencies, Boolean designTime)
at Microsoft.EntityFrameworkCore.Internal.DbContextServices.CreateModel(Boolean designTime)
at Microsoft.EntityFrameworkCore.Internal.DbContextServices.get_Model()
at Microsoft.EntityFrameworkCore.Infrastructure.EntityFrameworkServicesBuilder.<>c.<TryAddCoreServices>b__8_4(IServiceProvider p)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType) I did a workaround by writing a custom converter from using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace Sample.EFCore.ArrayPrimitiveTypes.Storage.Converters;
public class TagsValueConverter : ValueConverter<IReadOnlyCollection<string>, string[]>
{
public TagsValueConverter() : base(
value => value.ToArray(),
dbValue => dbValue.ToList())
{
}
} |
@shahabganji please open a new issue with a fully, runnable code sample that reproduces the exception. |
Fixes #14762