From 4ab52e07a0be7a580e2864a9981a1547d67d12df Mon Sep 17 00:00:00 2001 From: Arthur Vickers Date: Sat, 23 May 2020 14:35:29 -0700 Subject: [PATCH] Small updates Fixes #20900 Fixes #20843 Fixes #20837 Fixes #19462 Fixes #18910 --- .../Design/IAnnotationCodeGenerator.cs | 8 +- .../Storage/RelationalDatabaseCreator.cs | 14 + .../Diagnostics/CoreLoggerExtensions.cs | 4 +- ...ityFrameworkServiceCollectionExtensions.cs | 300 ++++++++++-------- src/EFCore/Infrastructure/DatabaseFacade.cs | 14 + src/EFCore/Infrastructure/ProductInfo.cs | 10 +- .../RequiredNavigationAttributeConvention.cs | 2 +- src/EFCore/Metadata/MemberIdentity.cs | 39 ++- .../NavigationAttributeConventionTest.cs | 2 +- 9 files changed, 252 insertions(+), 141 deletions(-) diff --git a/src/EFCore.Relational/Design/IAnnotationCodeGenerator.cs b/src/EFCore.Relational/Design/IAnnotationCodeGenerator.cs index 3d1f01105c0..6824b773430 100644 --- a/src/EFCore.Relational/Design/IAnnotationCodeGenerator.cs +++ b/src/EFCore.Relational/Design/IAnnotationCodeGenerator.cs @@ -20,7 +20,7 @@ public interface IAnnotationCodeGenerator /// /// The . /// The . - /// True if the annotation is handled by convention; false if code must be generated. + /// if the annotation is handled by convention; if code must be generated. bool IsHandledByConvention([NotNull] IModel model, [NotNull] IAnnotation annotation); /// @@ -29,7 +29,7 @@ public interface IAnnotationCodeGenerator /// /// The . /// The . - /// True if the annotation is handled by convention; false if code must be generated. + /// if the annotation is handled by convention; if code must be generated. bool IsHandledByConvention([NotNull] IEntityType entityType, [NotNull] IAnnotation annotation); /// @@ -38,6 +38,7 @@ public interface IAnnotationCodeGenerator /// /// The . /// The . + /// if the annotation is handled by convention; if code must be generated. bool IsHandledByConvention([NotNull] IKey key, [NotNull] IAnnotation annotation); /// @@ -46,6 +47,7 @@ public interface IAnnotationCodeGenerator /// /// The . /// The . + /// if the annotation is handled by convention; if code must be generated. bool IsHandledByConvention([NotNull] IProperty property, [NotNull] IAnnotation annotation); /// @@ -54,6 +56,7 @@ public interface IAnnotationCodeGenerator /// /// The . /// The . + /// if the annotation is handled by convention; if code must be generated. bool IsHandledByConvention([NotNull] IForeignKey foreignKey, [NotNull] IAnnotation annotation); /// @@ -62,6 +65,7 @@ public interface IAnnotationCodeGenerator /// /// The . /// The . + /// if the annotation is handled by convention; if code must be generated. bool IsHandledByConvention([NotNull] IIndex index, [NotNull] IAnnotation annotation); /// diff --git a/src/EFCore.Relational/Storage/RelationalDatabaseCreator.cs b/src/EFCore.Relational/Storage/RelationalDatabaseCreator.cs index 2d3e5734f71..87c719fc4bd 100644 --- a/src/EFCore.Relational/Storage/RelationalDatabaseCreator.cs +++ b/src/EFCore.Relational/Storage/RelationalDatabaseCreator.cs @@ -308,6 +308,13 @@ public virtual string GenerateCreateScript() /// Determines whether or not the database is available and can be connected to. /// /// + /// Any exceptions thrown when attempting to connect are caught and not propagated to the application. + /// + /// + /// The configured connection string is used to create the connection in the normal way, so all + /// configured options such as timeouts are honored. + /// + /// /// Note that being able to connect to the database does not mean that it is /// up-to-date with regard to schema creation, etc. /// @@ -330,6 +337,13 @@ public virtual bool CanConnect() /// Determines whether or not the database is available and can be connected to. /// /// + /// Any exceptions thrown when attempting to connect are caught and not propagated to the application. + /// + /// + /// The configured connection string is used to create the connection in the normal way, so all + /// configured options such as timeouts are honored. + /// + /// /// Note that being able to connect to the database does not mean that it is /// up-to-date with regard to schema creation, etc. /// diff --git a/src/EFCore/Diagnostics/CoreLoggerExtensions.cs b/src/EFCore/Diagnostics/CoreLoggerExtensions.cs index 41ba14f9b02..1258501bbed 100644 --- a/src/EFCore/Diagnostics/CoreLoggerExtensions.cs +++ b/src/EFCore/Diagnostics/CoreLoggerExtensions.cs @@ -1417,7 +1417,7 @@ public static void RequiredAttributeOnCollection( if (diagnostics.ShouldLog(definition)) { - definition.Log(diagnostics,navigation.Name,navigation.DeclaringEntityType.DisplayName()); + definition.Log(diagnostics, navigation.DeclaringEntityType.DisplayName(), navigation.Name); } if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) @@ -1435,7 +1435,7 @@ private static string RequiredAttributeOnCollection(EventDefinitionBase definiti { var d = (EventDefinition)definition; var p = (NavigationEventData)payload; - return d.GenerateMessage(p.Navigation.Name, p.Navigation.DeclaringEntityType.DisplayName()); + return d.GenerateMessage(p.Navigation.DeclaringEntityType.DisplayName(), p.Navigation.Name); } /// diff --git a/src/EFCore/Extensions/EntityFrameworkServiceCollectionExtensions.cs b/src/EFCore/Extensions/EntityFrameworkServiceCollectionExtensions.cs index 77db6273286..79f6f9cea34 100644 --- a/src/EFCore/Extensions/EntityFrameworkServiceCollectionExtensions.cs +++ b/src/EFCore/Extensions/EntityFrameworkServiceCollectionExtensions.cs @@ -22,20 +22,20 @@ namespace Microsoft.Extensions.DependencyInjection public static class EntityFrameworkServiceCollectionExtensions { /// - /// Registers the given context as a service in the . - /// You use this method when using dependency injection in your application, such as with ASP.NET. - /// For more information on setting up dependency injection, see http://go.microsoft.com/fwlink/?LinkId=526890. + /// + /// Registers the given context as a service in the . + /// + /// + /// Use this method when using dependency injection in your application, such as with ASP.NET Core. + /// For applications that don't use dependency injection, consider creating + /// instances directly with its constructor. The can then be + /// overridden to configure a connection string and other options. + /// + /// + /// For more information on how to use this method, see the Entity Framework Core documentation at https://aka.ms/efdocs. + /// For more information on using dependency injection, see https://go.microsoft.com/fwlink/?LinkId=526890. + /// /// - /// - /// - /// public void ConfigureServices(IServiceCollection services) - /// { - /// var connectionString = "connection string to database"; - /// - /// services.AddDbContext<MyContext>(options => options.UseSqlServer(connectionString)); - /// } - /// - /// /// The type of context to be registered. /// The to add services to. /// @@ -68,20 +68,20 @@ public static IServiceCollection AddDbContext( => AddDbContext(serviceCollection, optionsAction, contextLifetime, optionsLifetime); /// - /// Registers the given context as a service in the . - /// You use this method when using dependency injection in your application, such as with ASP.NET. - /// For more information on setting up dependency injection, see http://go.microsoft.com/fwlink/?LinkId=526890. + /// + /// Registers the given context as a service in the . + /// + /// + /// Use this method when using dependency injection in your application, such as with ASP.NET Core. + /// For applications that don't use dependency injection, consider creating + /// instances directly with its constructor. The can then be + /// overridden to configure a connection string and other options. + /// + /// + /// For more information on how to use this method, see the Entity Framework Core documentation at https://aka.ms/efdocs. + /// For more information on using dependency injection, see https://go.microsoft.com/fwlink/?LinkId=526890. + /// /// - /// - /// - /// public void ConfigureServices(IServiceCollection services) - /// { - /// var connectionString = "connection string to database"; - /// - /// services.AddDbContext<MyContext>(options => options.UseSqlServer(connectionString)); - /// } - /// - /// /// The class or interface that will be used to resolve the context from the container. /// The concrete implementation type to create. /// The to add services to. @@ -119,11 +119,27 @@ public static IServiceCollection AddDbContext optionsAction.Invoke(b), contextLifetime, optionsLifetime); /// - /// Registers the given context as a service in the and enables DbContext pooling. - /// Instance pooling can increase throughput in high-scale scenarios such as web servers by re-using - /// DbContext instances, rather than creating new instances for each request. - /// You use this method when using dependency injection in your application, such as with ASP.NET. - /// For more information on setting up dependency injection, see http://go.microsoft.com/fwlink/?LinkId=526890. + /// + /// Registers the given as a service in the , + /// and enables DbContext pooling for this registration. + /// + /// DbContext pooling can increase performance in high-throughput scenarios by re-using context instances. + /// However, for most application this performance gain is very small. + /// Note that when using pooling, the context configuration cannot change between uses, and scoped services + /// injected into the context will only be resolved once from the initial scope. + /// Only consider using DbContext pooling when performance testing indicates it provides a real boost. + /// + /// + /// + /// Use this method when using dependency injection in your application, such as with ASP.NET Core. + /// For applications that don't use dependency injection, consider creating + /// instances directly with its constructor. The can then be + /// overridden to configure a connection string and other options. + /// + /// + /// For more information on how to use this method, see the Entity Framework Core documentation at https://aka.ms/efdocs. + /// For more information on using dependency injection, see https://go.microsoft.com/fwlink/?LinkId=526890. + /// /// /// The type of context to be registered. /// The to add services to. @@ -148,11 +164,27 @@ public static IServiceCollection AddDbContextPool( => AddDbContextPool(serviceCollection, optionsAction, poolSize); /// - /// Registers the given context as a service in the and enables DbContext pooling. - /// Instance pooling can increase throughput in high-scale scenarios such as web servers by re-using - /// DbContext instances, rather than creating new instances for each request. - /// You use this method when using dependency injection in your application, such as with ASP.NET. - /// For more information on setting up dependency injection, see http://go.microsoft.com/fwlink/?LinkId=526890. + /// + /// Registers the given as a service in the , + /// and enables DbContext pooling for this registration. + /// + /// DbContext pooling can increase performance in high-throughput scenarios by re-using context instances. + /// However, for most application this performance gain is very small. + /// Note that when using pooling, the context configuration cannot change between uses, and scoped services + /// injected into the context will only be resolved once from the initial scope. + /// Only consider using DbContext pooling when performance testing indicates it provides a real boost. + /// + /// + /// + /// Use this method when using dependency injection in your application, such as with ASP.NET Core. + /// For applications that don't use dependency injection, consider creating + /// instances directly with its constructor. The can then be + /// overridden to configure a connection string and other options. + /// + /// + /// For more information on how to use this method, see the Entity Framework Core documentation at https://aka.ms/efdocs. + /// For more information on using dependency injection, see https://go.microsoft.com/fwlink/?LinkId=526890. + /// /// /// The class or interface that will be used to resolve the context from the container. /// The concrete implementation type to create. @@ -184,19 +216,32 @@ public static IServiceCollection AddDbContextPool /// - /// Registers the given context as a service in the and enables DbContext pooling. - /// Instance pooling can increase throughput in high-scale scenarios such as web servers by re-using - /// DbContext instances, rather than creating new instances for each request. - /// You use this method when using dependency injection in your application, such as with ASP.NET. - /// For more information on setting up dependency injection, see http://go.microsoft.com/fwlink/?LinkId=526890. + /// Registers the given as a service in the , + /// and enables DbContext pooling for this registration. + /// + /// DbContext pooling can increase performance in high-throughput scenarios by re-using context instances. + /// However, for most application this performance gain is very small. + /// Note that when using pooling, the context configuration cannot change between uses, and scoped services + /// injected into the context will only be resolved once from the initial scope. + /// Only consider using DbContext pooling when performance testing indicates it provides a real boost. + /// /// /// - /// This overload has an that provides the applications . - /// This is useful if you want to setup Entity Framework to resolve its internal services from the primary application service - /// provider. - /// By default, we recommend using the other overload, which allows Entity Framework to create and maintain its own - /// - /// for internal Entity Framework services. + /// Use this method when using dependency injection in your application, such as with ASP.NET Core. + /// For applications that don't use dependency injection, consider creating + /// instances directly with its constructor. The can then be + /// overridden to configure a connection string and other options. + /// + /// + /// For more information on how to use this method, see the Entity Framework Core documentation at https://aka.ms/efdocs. + /// For more information on using dependency injection, see https://go.microsoft.com/fwlink/?LinkId=526890. + /// + /// + /// This overload has an that provides the applications + /// . This is useful if you want to setup Entity Framework Core to resolve + /// its internal services from the primary application service provider. + /// By default, we recommend using the other overload, which allows Entity Framework to create and maintain + /// its own for internal Entity Framework services. /// /// /// The type of context to be registered. @@ -223,19 +268,32 @@ public static IServiceCollection AddDbContextPool( /// /// - /// Registers the given context as a service in the and enables DbContext pooling. - /// Instance pooling can increase throughput in high-scale scenarios such as web servers by re-using - /// DbContext instances, rather than creating new instances for each request. - /// You use this method when using dependency injection in your application, such as with ASP.NET. - /// For more information on setting up dependency injection, see http://go.microsoft.com/fwlink/?LinkId=526890. + /// Registers the given as a service in the , + /// and enables DbContext pooling for this registration. + /// + /// DbContext pooling can increase performance in high-throughput scenarios by re-using context instances. + /// However, for most application this performance gain is very small. + /// Note that when using pooling, the context configuration cannot change between uses, and scoped services + /// injected into the context will only be resolved once from the initial scope. + /// Only consider using DbContext pooling when performance testing indicates it provides a real boost. + /// + /// + /// + /// Use this method when using dependency injection in your application, such as with ASP.NET Core. + /// For applications that don't use dependency injection, consider creating + /// instances directly with its constructor. The can then be + /// overridden to configure a connection string and other options. /// /// - /// This overload has an that provides the applications . - /// This is useful if you want to setup Entity Framework to resolve its internal services from the primary application service - /// provider. - /// By default, we recommend using the other overload, which allows Entity Framework to create and maintain its own - /// - /// for internal Entity Framework services. + /// For more information on how to use this method, see the Entity Framework Core documentation at https://aka.ms/efdocs. + /// For more information on using dependency injection, see https://go.microsoft.com/fwlink/?LinkId=526890. + /// + /// + /// This overload has an that provides the applications + /// . This is useful if you want to setup Entity Framework Core to resolve + /// its internal services from the primary application service provider. + /// By default, we recommend using the other overload, which allows Entity Framework to create and maintain + /// its own for internal Entity Framework services. /// /// /// The class or interface that will be used to resolve the context from the container. @@ -297,20 +355,20 @@ public static IServiceCollection AddDbContextPool - /// Registers the given context as a service in the . - /// You use this method when using dependency injection in your application, such as with ASP.NET. - /// For more information on setting up dependency injection, see http://go.microsoft.com/fwlink/?LinkId=526890. + /// + /// Registers the given context as a service in the . + /// + /// + /// Use this method when using dependency injection in your application, such as with ASP.NET Core. + /// For applications that don't use dependency injection, consider creating + /// instances directly with its constructor. The can then be + /// overridden to configure a connection string and other options. + /// + /// + /// For more information on how to use this method, see the Entity Framework Core documentation at https://aka.ms/efdocs. + /// For more information on using dependency injection, see https://go.microsoft.com/fwlink/?LinkId=526890. + /// /// - /// - /// - /// public void ConfigureServices(IServiceCollection services) - /// { - /// var connectionString = "connection string to database"; - /// - /// services.AddDbContext<MyContext>(ServiceLifetime.Scoped); - /// } - /// - /// /// The type of context to be registered. /// The to add services to. /// The lifetime with which to register the DbContext service in the container. @@ -326,20 +384,20 @@ public static IServiceCollection AddDbContext( => AddDbContext(serviceCollection, contextLifetime, optionsLifetime); /// - /// Registers the given context as a service in the . - /// You use this method when using dependency injection in your application, such as with ASP.NET. - /// For more information on setting up dependency injection, see http://go.microsoft.com/fwlink/?LinkId=526890. + /// + /// Registers the given context as a service in the . + /// + /// + /// Use this method when using dependency injection in your application, such as with ASP.NET Core. + /// For applications that don't use dependency injection, consider creating + /// instances directly with its constructor. The can then be + /// overridden to configure a connection string and other options. + /// + /// + /// For more information on how to use this method, see the Entity Framework Core documentation at https://aka.ms/efdocs. + /// For more information on using dependency injection, see https://go.microsoft.com/fwlink/?LinkId=526890. + /// /// - /// - /// - /// public void ConfigureServices(IServiceCollection services) - /// { - /// var connectionString = "connection string to database"; - /// - /// services.AddDbContext<MyContext>(ServiceLifetime.Scoped); - /// } - /// - /// /// The class or interface that will be used to resolve the context from the container. /// The concrete implementation type to create. /// The to add services to. @@ -363,32 +421,25 @@ public static IServiceCollection AddDbContext /// /// Registers the given context as a service in the . - /// You use this method when using dependency injection in your application, such as with ASP.NET. - /// For more information on setting up dependency injection, see http://go.microsoft.com/fwlink/?LinkId=526890. /// /// - /// This overload has an that provides the applications . - /// This is useful if you want to setup Entity Framework to resolve its internal services from the primary application service - /// provider. - /// By default, we recommend using the other overload, which allows Entity Framework to create and maintain its own - /// - /// for internal Entity Framework services. + /// Use this method when using dependency injection in your application, such as with ASP.NET Core. + /// For applications that don't use dependency injection, consider creating + /// instances directly with its constructor. The can then be + /// overridden to configure a connection string and other options. + /// + /// + /// For more information on how to use this method, see the Entity Framework Core documentation at https://aka.ms/efdocs. + /// For more information on using dependency injection, see https://go.microsoft.com/fwlink/?LinkId=526890. + /// + /// + /// This overload has an that provides the applications + /// . This is useful if you want to setup Entity Framework Core to resolve + /// its internal services from the primary application service provider. + /// By default, we recommend using the other overload, which allows Entity Framework to create and maintain + /// its own for internal Entity Framework services. /// /// - /// - /// - /// public void ConfigureServices(IServiceCollection services) - /// { - /// var connectionString = "connection string to database"; - /// - /// services - /// .AddEntityFrameworkSqlServer() - /// .AddDbContext<MyContext>((serviceProvider, options) => - /// options.UseSqlServer(connectionString) - /// .UseInternalServiceProvider(serviceProvider)); - /// } - /// - /// /// The type of context to be registered. /// The to add services to. /// @@ -423,32 +474,25 @@ public static IServiceCollection AddDbContext( /// /// /// Registers the given context as a service in the . - /// You use this method when using dependency injection in your application, such as with ASP.NET. - /// For more information on setting up dependency injection, see http://go.microsoft.com/fwlink/?LinkId=526890. /// /// - /// This overload has an that provides the applications . - /// This is useful if you want to setup Entity Framework to resolve its internal services from the primary application service - /// provider. - /// By default, we recommend using the other overload, which allows Entity Framework to create and maintain its own - /// - /// for internal Entity Framework services. + /// Use this method when using dependency injection in your application, such as with ASP.NET Core. + /// For applications that don't use dependency injection, consider creating + /// instances directly with its constructor. The can then be + /// overridden to configure a connection string and other options. + /// + /// + /// For more information on how to use this method, see the Entity Framework Core documentation at https://aka.ms/efdocs. + /// For more information on using dependency injection, see https://go.microsoft.com/fwlink/?LinkId=526890. + /// + /// + /// This overload has an that provides the applications + /// . This is useful if you want to setup Entity Framework Core to resolve + /// its internal services from the primary application service provider. + /// By default, we recommend using the other overload, which allows Entity Framework to create and maintain + /// its own for internal Entity Framework services. /// /// - /// - /// - /// public void ConfigureServices(IServiceCollection services) - /// { - /// var connectionString = "connection string to database"; - /// - /// services - /// .AddEntityFrameworkSqlServer() - /// .AddDbContext<MyContext>((serviceProvider, options) => - /// options.UseSqlServer(connectionString) - /// .UseInternalServiceProvider(serviceProvider)); - /// } - /// - /// /// The class or interface that will be used to resolve the context from the container. /// The concrete implementation type to create. /// The to add services to. diff --git a/src/EFCore/Infrastructure/DatabaseFacade.cs b/src/EFCore/Infrastructure/DatabaseFacade.cs index 467e79bc892..3708a1827d3 100644 --- a/src/EFCore/Infrastructure/DatabaseFacade.cs +++ b/src/EFCore/Infrastructure/DatabaseFacade.cs @@ -112,6 +112,13 @@ public virtual Task EnsureDeletedAsync(CancellationToken cancellationToken /// Determines whether or not the database is available and can be connected to. /// /// + /// Any exceptions thrown when attempting to connect are caught and not propagated to the application. + /// + /// + /// The configured connection string is used to create the connection in the normal way, so all + /// configured options such as timeouts are honored. + /// + /// /// Note that being able to connect to the database does not mean that it is /// up-to-date with regard to schema creation, etc. /// @@ -125,6 +132,13 @@ public virtual bool CanConnect() /// Determines whether or not the database is available and can be connected to. /// /// + /// Any exceptions thrown when attempting to connect are caught and not propagated to the application. + /// + /// + /// The configured connection string is used to create the connection in the normal way, so all + /// configured options such as timeouts are honored. + /// + /// /// Note that being able to connect to the database does not mean that it is /// up-to-date with regard to schema creation, etc. /// diff --git a/src/EFCore/Infrastructure/ProductInfo.cs b/src/EFCore/Infrastructure/ProductInfo.cs index ecbad7949a8..2e339311acc 100644 --- a/src/EFCore/Infrastructure/ProductInfo.cs +++ b/src/EFCore/Infrastructure/ProductInfo.cs @@ -5,12 +5,18 @@ namespace Microsoft.EntityFrameworkCore.Infrastructure { -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member See issue#20837 + /// + /// Helper class for finding the version of Entity Framework Core being used. + /// public static class ProductInfo { + /// + /// Gets the value of the + /// for the EntityFrameworkCore assembly. + /// + /// The EF Core version being used. public static string GetVersion() => typeof(ProductInfo).Assembly .GetCustomAttribute().InformationalVersion; } -#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member } diff --git a/src/EFCore/Metadata/Conventions/RequiredNavigationAttributeConvention.cs b/src/EFCore/Metadata/Conventions/RequiredNavigationAttributeConvention.cs index e8e342bd858..741ceca745e 100644 --- a/src/EFCore/Metadata/Conventions/RequiredNavigationAttributeConvention.cs +++ b/src/EFCore/Metadata/Conventions/RequiredNavigationAttributeConvention.cs @@ -35,7 +35,7 @@ public override void ProcessNavigationAdded( var foreignKey = navigation.ForeignKey; if (navigation.IsCollection) { - Dependencies.Logger.RequiredAttributeOnCollection(foreignKey.DependentToPrincipal); + Dependencies.Logger.RequiredAttributeOnCollection(navigation); return; } diff --git a/src/EFCore/Metadata/MemberIdentity.cs b/src/EFCore/Metadata/MemberIdentity.cs index 48e6a0481de..1b899d12f30 100644 --- a/src/EFCore/Metadata/MemberIdentity.cs +++ b/src/EFCore/Metadata/MemberIdentity.cs @@ -8,20 +8,27 @@ namespace Microsoft.EntityFrameworkCore.Metadata { /// - /// Represents the identity of an entity type member, can be based on or just the name. + /// Represents the identity of an entity type member, can be based on or just the name. /// [DebuggerDisplay("{DebuggerDisplay(),nq}")] public readonly struct MemberIdentity { private readonly object _nameOrMember; + /// + /// Constructs a new from the given member name. + /// + /// The member name. [DebuggerStepThrough] -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member See issue#20837 public MemberIdentity([NotNull] string name) : this((object)name) { } + /// + /// Constructs a new from the given . + /// + /// The member. [DebuggerStepThrough] public MemberIdentity([NotNull] MemberInfo memberInfo) : this((object)memberInfo) @@ -34,23 +41,46 @@ private MemberIdentity([CanBeNull] object nameOrMember) _nameOrMember = nameOrMember; } + /// + /// Checks if the identity is empty, as opposed to representing a member. + /// + /// if the identity is empty; otherwise. public bool IsNone() => _nameOrMember == null; + /// + /// A instance that does not represent any member. + /// public static readonly MemberIdentity None = new MemberIdentity((object)null); + /// + /// Creates a new from the given member name. + /// + /// The member name. + /// The newly created identity, or if the given name is . [DebuggerStepThrough] public static MemberIdentity Create([CanBeNull] string name) => name == null ? None : new MemberIdentity(name); + /// + /// Creates a new from the given . + /// + /// The member. + /// The newly created identity, or if the given name is . [DebuggerStepThrough] - public static MemberIdentity Create([CanBeNull] MemberInfo member) - => member == null ? None : new MemberIdentity(member); + public static MemberIdentity Create([CanBeNull] MemberInfo memberInfo) + => memberInfo == null ? None : new MemberIdentity(memberInfo); + /// + /// The name of the member. + /// public string Name { [DebuggerStepThrough] get => MemberInfo?.GetSimpleMemberName() ?? (string)_nameOrMember; } + /// + /// The representing the member, or if not known. + /// public MemberInfo MemberInfo { [DebuggerStepThrough] get => _nameOrMember as MemberInfo; @@ -58,6 +88,5 @@ public MemberInfo MemberInfo private string DebuggerDisplay() => Name ?? "NONE"; -#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member } } diff --git a/test/EFCore.Tests/Metadata/Conventions/NavigationAttributeConventionTest.cs b/test/EFCore.Tests/Metadata/Conventions/NavigationAttributeConventionTest.cs index 91373678cb7..aff77d12826 100644 --- a/test/EFCore.Tests/Metadata/Conventions/NavigationAttributeConventionTest.cs +++ b/test/EFCore.Tests/Metadata/Conventions/NavigationAttributeConventionTest.cs @@ -169,7 +169,7 @@ public void RequiredAttribute_does_not_set_is_required_for_collection_navigation Assert.Equal(LogLevel.Debug, logEntry.Level); Assert.Equal( CoreResources.LogRequiredAttributeOnCollection(new TestLogger()).GenerateMessage( - nameof(Principal), nameof(Principal.Dependent)), logEntry.Message); + nameof(Principal), nameof(Principal.Dependents)), logEntry.Message); } [ConditionalFact]