Skip to content
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

Pre-convention model configuration #12229

Closed
Tracked by #22952
ajcvickers opened this issue Jun 4, 2018 · 4 comments · Fixed by #24993
Closed
Tracked by #22952

Pre-convention model configuration #12229

ajcvickers opened this issue Jun 4, 2018 · 4 comments · Fixed by #24993
Labels
area-conventions area-model-building closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. type-enhancement
Milestone

Comments

@ajcvickers
Copy link
Contributor

ajcvickers commented Jun 4, 2018

Doing an initial discovery of the model based only on DbSet roots was a reasonable approach when it was reasonably easy to distinguish likely scalar properties from likely navigation properties. However, as we allow more an more types to be mapped it has become increasingly problematic to

  • Exclude a type as an entity type and therefore avoid trying to bring it and all its properties into the model
  • Revert a type from being an entity type when a value converter is found or the type is ignored.

This results in both bugs and additional overhead.

Therefore, this issue is about finding ways to enhance model building so that it can more efficiently figure out what is an entity type and what is not. Some ideas:

  • Some up-front configuration that defines either types that are entity types, or types that are not entity types. This would be provided before model building begins, possibly using model customization or lifecycle hooks.
  • Up-front configuration for value converters, which would provide partial info on types that are not entity types.
@ajcvickers
Copy link
Contributor Author

The initial work here is to investigate and have some initial design discussions about ways we could go.

@AndriySvyryd
Copy link
Member

AndriySvyryd commented Dec 18, 2018

The up-front configuration should be non-interactive (i.e. no conventions will be running before it is finished and there won't be a way to get the current model). Thus it requires new API separate from ModelBuilder (but still following the same patterns).

Proposal: DbContext.OnModelBuiderCreating(ModelConfigurationBuilder configurationBuilder)

Related to #6787, #3867, #10784, #20418

@AndriySvyryd
Copy link
Member

Also modelBuilder.Owned<>() should be moved to the new API.

@AndriySvyryd
Copy link
Member

AndriySvyryd commented May 18, 2021

A more detailed proposal:

protected internal virtual void ConfigureConventions(ModelConfigurationBuilder configurationBuilder);
public class ModelConfigurationBuilder
{
    public ModelConfigurationBuilder(ConventionSet conventions);

    public ConventionSetBuilder Conventions { get; }

    public virtual EntityTypesConfigurationBuilder Entities();
    public virtual ModelConfigurationBuilder Entities(Action<EntityTypesConfigurationBuilder> buildAction);
    public virtual EntityTypesConfigurationBuilder Entities(Type type);
    public virtual ModelConfigurationBuilder Entities(Type type, Action<EntityTypesConfigurationBuilder> buildAction);

    public virtual EntityTypesConfigurationBuilder SharedTypeEntities();
    public virtual ModelConfigurationBuilder SharedTypeEntities(Action<EntityTypesConfigurationBuilder> buildAction);
    public virtual EntityTypesConfigurationBuilder SharedTypeEntities(Type type);
    public virtual ModelConfigurationBuilder SharedTypeEntities(Type type, Action<EntityTypesConfigurationBuilder> buildAction);

    public virtual OwnedEntityTypesConfigurationBuilder OwnedEntities();
    public virtual ModelConfigurationBuilder OwnedEntities(Type type);
    public virtual OwnedEntityTypesConfigurationBuilder OwnedEntities(Type type);
    public virtual ModelConfigurationBuilder OwnedEntities(Type type, Action<OwnedEntityTypesConfigurationBuilder> buildAction);

    public virtual ModelConfigurationBuilder IgnoreAny(Type type);

    public virtual PropertiesConfigurationBuilder Properties(Type propertyType);
    public virtual ModelConfigurationBuilder Properties(Type propertyType, Action<PropertiesConfigurationBuilder> buildAction);

    public virtual ServicePropertiesConfigurationBuilder ServiceProperties(Type propertyType);
    public virtual ModelConfigurationBuilder ServiceProperties(Type propertyType, Action<ServicePropertiesConfigurationBuilder> buildAction);
    public virtual ModelBuilder InitializeModelBuilder(ModelDependencies modelDependencies);
}
public class PropertiesConfigurationBuilder
{
    [EntityFrameworkInternal]
    public PropertiesConfigurationBuilder(PropertiesConfiguration property);

    public virtual PropertiesConfigurationBuilder HaveAnnotation(string annotation, object? value);
    public virtual PropertiesConfigurationBuilder HaveMaxLength(int maxLength);
    public virtual PropertiesConfigurationBuilder HavePrecision(int precision, int scale);
    public virtual PropertiesConfigurationBuilder HavePrecision(int precision);
    public virtual PropertiesConfigurationBuilder AreUnicode(bool unicode = true);
    public virtual PropertiesConfigurationBuilder HaveConversion(Type providerClrType);
    public virtual PropertiesConfigurationBuilder HaveConversion(Type converterType, Type comparerType);
}

Calling these methods will have no immediate effect on the model. But when a type is discovered by convention any configuration specified for it or any base type or implemented interface will be applied at that point. The configuration specified using ModelConfigurationBuilder is considered Explicit

Last one wins for multiple conflicting configurations for the same type.

An exception is thrown when base types have conflicting configurations, unless overridden by Fluent API.

@AndriySvyryd AndriySvyryd added closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. and removed needs-design labels May 27, 2021
@AndriySvyryd AndriySvyryd removed their assignment May 27, 2021
AndriySvyryd added a commit that referenced this issue May 27, 2021
Allow to Ignore entity types and properties by base type or interface
Allow to specify a value conversion and other facets for all properties of a given type

Fixes #12229
Fixes #3867
Fixes #10784
@AndriySvyryd AndriySvyryd modified the milestones: 6.0.0, 6.0.0-preview6 Jul 2, 2021
@ajcvickers ajcvickers modified the milestones: 6.0.0-preview6, 6.0.0 Nov 8, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-conventions area-model-building closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. type-enhancement
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants