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

Raw SQL queries for unmapped types #29931

Merged
merged 42 commits into from
Jan 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
d9d96e4
Merge in 'release/7.0' changes
dotnet-bot Nov 1, 2022
ea019b0
Merge in 'release/6.0' changes
dotnet-bot Nov 1, 2022
47ac39d
Merge in 'release/7.0' changes
dotnet-bot Nov 2, 2022
2627f28
Merge in 'release/6.0' changes
dotnet-bot Nov 2, 2022
8be3619
Merge in 'release/6.0' changes
dotnet-bot Nov 2, 2022
c597473
Merge in 'release/6.0' changes
dotnet-bot Nov 2, 2022
baac22d
Merge in 'release/7.0' changes
dotnet-bot Nov 2, 2022
be469e6
Merge in 'release/6.0' changes
dotnet-bot Nov 2, 2022
23415d7
Merge in 'release/6.0' changes
dotnet-bot Nov 7, 2022
0544093
Merge in 'release/7.0' changes
dotnet-bot Nov 7, 2022
1addb2c
Merge in 'release/6.0' changes
dotnet-bot Nov 8, 2022
4e75722
Merge in 'release/6.0' changes
dotnet-bot Nov 8, 2022
1d70400
Merge in 'release/7.0' changes
dotnet-bot Nov 8, 2022
876c649
Merge in 'release/6.0' changes
dotnet-bot Nov 9, 2022
8b903ca
Merge in 'release/7.0' changes
dotnet-bot Nov 9, 2022
3f2189a
Merge in 'release/7.0' changes
dotnet-bot Nov 9, 2022
1bad91e
Merge in 'release/7.0' changes
dotnet-bot Nov 9, 2022
481b2a4
Merge in 'release/6.0' changes
dotnet-bot Nov 12, 2022
7c6d80e
Merge in 'release/6.0' changes
dotnet-bot Nov 14, 2022
3c59122
Merge in 'release/7.0' changes
dotnet-bot Nov 14, 2022
74dc918
Merge in 'release/6.0' changes
dotnet-bot Nov 14, 2022
3317439
Merge in 'release/7.0' changes
dotnet-bot Nov 29, 2022
2652c51
Merge in 'release/6.0' changes
dotnet-bot Nov 29, 2022
40757ed
Merge in 'release/7.0' changes
dotnet-bot Nov 29, 2022
6f19635
Merge in 'release/6.0' changes
dotnet-bot Nov 30, 2022
6c479ce
Merge in 'release/7.0' changes
dotnet-bot Nov 30, 2022
f48dbe7
Merge in 'release/6.0' changes
dotnet-bot Nov 30, 2022
0c8605d
Merge in 'release/7.0' changes
dotnet-bot Nov 30, 2022
351cd7b
Merge commit 'f48dbe7321a44cd4aa3e22986beb208e559e3919' into internal…
vseanreesermsft Jan 10, 2023
ac61b0b
Merge commit '0c8605d87b88157c773efd70ed2b8546ef18d5a1' into internal…
vseanreesermsft Jan 10, 2023
c8fa08b
Move to 7.0.102 .NET SDK
dougbu Jan 11, 2023
1bf4c45
Move to 6.0.113 SDK and 3.1.32 runtime
dougbu Jan 11, 2023
9dbdfb6
Merge pull request #30018 from vseanreesermsft/internal-merge-7.0-202…
dougbu Jan 11, 2023
7199547
Merge pull request #30017 from vseanreesermsft/internal-merge-6.0-202…
dougbu Jan 11, 2023
23e88e8
Raw SQL queries for unmapped types
ajcvickers Dec 26, 2022
3f2736a
Removed convention to add AdHoc annotation
ajcvickers Jan 11, 2023
7ff89d3
Merge branch 'release/6.0' into release/7.0
ajcvickers Jan 11, 2023
1ac1857
Merge branch 'release/7.0'
ajcvickers Jan 11, 2023
ae52a0d
Raw SQL queries for unmapped types
ajcvickers Dec 26, 2022
acfa6b4
Removed convention to add AdHoc annotation
ajcvickers Jan 11, 2023
75539c8
Merge branch 'WhatIfWeDidThis1224' of https://github.com/dotnet/efcor…
ajcvickers Jan 12, 2023
f4a6298
Review updates.
ajcvickers Jan 12, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions global.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"tools": {
"dotnet": "7.0.100"
"dotnet": "7.0.102"
},
"sdk": {
"version": "7.0.100",
"version": "7.0.102",
"allowPrerelease": true,
"rollForward": "latestMajor"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -340,11 +340,14 @@ public static IQueryable<TResult> SqlQueryRaw<TResult>(
Check.NotNull(parameters, nameof(parameters));

var facadeDependencies = GetFacadeDependencies(databaseFacade);

return facadeDependencies.QueryProvider
.CreateQuery<TResult>(
new SqlQueryRootExpression(
facadeDependencies.QueryProvider, typeof(TResult), sql, Expression.Constant(parameters)));
var queryProvider = facadeDependencies.QueryProvider;
var argumentsExpression = Expression.Constant(parameters);

return queryProvider.CreateQuery<TResult>(
facadeDependencies.TypeMappingSource.FindMapping(typeof(TResult)) != null
? new SqlQueryRootExpression(queryProvider, typeof(TResult), sql, argumentsExpression)
: new FromSqlQueryRootExpression(
queryProvider, facadeDependencies.AdHocMapper.GetOrAddEntityType(typeof(TResult)), sql, argumentsExpression));
}

/// <summary>
Expand Down Expand Up @@ -380,17 +383,7 @@ public static IQueryable<TResult> SqlQueryRaw<TResult>(
public static IQueryable<TResult> SqlQuery<TResult>(
this DatabaseFacade databaseFacade,
[NotParameterized] FormattableString sql)
{
Check.NotNull(sql, nameof(sql));
Check.NotNull(sql.Format, nameof(sql.Format));

var facadeDependencies = GetFacadeDependencies(databaseFacade);

return facadeDependencies.QueryProvider
.CreateQuery<TResult>(
new SqlQueryRootExpression(
facadeDependencies.QueryProvider, typeof(TResult), sql.Format, Expression.Constant(sql.GetArguments())));
}
=> SqlQueryRaw<TResult>(databaseFacade, sql.Format, sql.GetArguments()!);

/// <summary>
/// Executes the given SQL against the database and returns the number of rows affected.
Expand Down Expand Up @@ -654,7 +647,7 @@ public static DbConnection GetDbConnection(this DatabaseFacade databaseFacade)
/// <param name="contextOwnsConnection">
/// If <see langword="true" />, then EF will take ownership of the connection and will
/// dispose it in the same way it would dispose a connection created by EF. If <see langword="false" />, then the caller still
/// owns the connection and is responsible for its disposal. The default value is <see langword="false"/>.
/// owns the connection and is responsible for its disposal. The default value is <see langword="false" />.
/// </param>
public static void SetDbConnection(this DatabaseFacade databaseFacade, DbConnection? connection, bool contextOwnsConnection = false)
=> GetFacadeDependencies(databaseFacade).RelationalConnection.SetDbConnection(connection, contextOwnsConnection);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ public RelationalDatabaseFacadeDependencies(
IRelationalConnection relationalConnection,
IRawSqlCommandBuilder rawSqlCommandBuilder,
ICoreSingletonOptions coreOptions,
IAsyncQueryProvider queryProvider)
IAsyncQueryProvider queryProvider,
IAdHocMapper adHocMapper,
IRelationalTypeMappingSource relationalTypeMappingSource)
{
TransactionManager = transactionManager;
DatabaseCreator = databaseCreator;
Expand All @@ -41,6 +43,8 @@ public RelationalDatabaseFacadeDependencies(
RawSqlCommandBuilder = rawSqlCommandBuilder;
CoreOptions = coreOptions;
QueryProvider = queryProvider;
AdHocMapper = adHocMapper;
TypeMappingSource = relationalTypeMappingSource;
}

/// <summary>
Expand All @@ -49,47 +53,47 @@ public RelationalDatabaseFacadeDependencies(
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public virtual IDbContextTransactionManager TransactionManager { get; init; }
public virtual IDbContextTransactionManager TransactionManager { get; }

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public virtual IDatabaseCreator DatabaseCreator { get; init; }
public virtual IDatabaseCreator DatabaseCreator { get; }

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public virtual IExecutionStrategy ExecutionStrategy { get; init; }
public virtual IExecutionStrategy ExecutionStrategy { get; }

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public virtual IExecutionStrategyFactory ExecutionStrategyFactory { get; init; }
public virtual IExecutionStrategyFactory ExecutionStrategyFactory { get; }

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public virtual IEnumerable<IDatabaseProvider> DatabaseProviders { get; init; }
public virtual IEnumerable<IDatabaseProvider> DatabaseProviders { get; }

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public virtual IRelationalCommandDiagnosticsLogger CommandLogger { get; init; }
public virtual IRelationalCommandDiagnosticsLogger CommandLogger { get; }

IDiagnosticsLogger<DbLoggerCategory.Database.Command> IDatabaseFacadeDependencies.CommandLogger
=> CommandLogger;
Expand All @@ -100,37 +104,53 @@ public RelationalDatabaseFacadeDependencies(
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public virtual IConcurrencyDetector ConcurrencyDetector { get; init; }
public virtual IConcurrencyDetector ConcurrencyDetector { get; }

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public virtual IRelationalConnection RelationalConnection { get; init; }
public virtual IRelationalConnection RelationalConnection { get; }

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public virtual IRawSqlCommandBuilder RawSqlCommandBuilder { get; init; }
public virtual IRawSqlCommandBuilder RawSqlCommandBuilder { get; }

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public virtual ICoreSingletonOptions CoreOptions { get; init; }
public virtual ICoreSingletonOptions CoreOptions { get; }

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public virtual IAsyncQueryProvider QueryProvider { get; init; }
public virtual IAsyncQueryProvider QueryProvider { get; }

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public virtual IAdHocMapper AdHocMapper { get; }

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public virtual ITypeMappingSource TypeMappingSource { get; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ namespace Microsoft.EntityFrameworkCore.Storage;
public class RelationalSqlGenerationHelper : ISqlGenerationHelper
{
/// <summary>
/// Initializes a new instance of the this class.
/// Initializes a new instance of this class.
/// </summary>
/// <param name="dependencies">Parameter object containing dependencies for this service.</param>
public RelationalSqlGenerationHelper(RelationalSqlGenerationHelperDependencies dependencies)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public abstract class RelationalTypeMappingSource : TypeMappingSourceBase, IRela
= new();

/// <summary>
/// Initializes a new instance of the this class.
/// Initializes a new instance of this class.
/// </summary>
/// <param name="dependencies">Parameter object containing dependencies for this service.</param>
/// <param name="relationalDependencies">Parameter object containing relational-specific dependencies for this service.</param>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ namespace Microsoft.EntityFrameworkCore.Update;
public abstract class UpdateAndSelectSqlGenerator : UpdateSqlGenerator
{
/// <summary>
/// Initializes a new instance of the this class.
/// Initializes a new instance of this class.
/// </summary>
/// <param name="dependencies">Parameter object containing dependencies for this service.</param>
protected UpdateAndSelectSqlGenerator(UpdateSqlGeneratorDependencies dependencies)
Expand Down
2 changes: 1 addition & 1 deletion src/EFCore.Relational/Update/UpdateSqlGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ namespace Microsoft.EntityFrameworkCore.Update;
public abstract class UpdateSqlGenerator : IUpdateSqlGenerator
{
/// <summary>
/// Initializes a new instance of the this class.
/// Initializes a new instance of this class.
/// </summary>
/// <param name="dependencies">Parameter object containing dependencies for this service.</param>
protected UpdateSqlGenerator(UpdateSqlGeneratorDependencies dependencies)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ public static readonly IDictionary<Type, ServiceCharacteristics> CoreServices
{ typeof(IQueryTranslationPostprocessorFactory), new ServiceCharacteristics(ServiceLifetime.Scoped) },
{ typeof(IShapedQueryCompilingExpressionVisitorFactory), new ServiceCharacteristics(ServiceLifetime.Scoped) },
{ typeof(IDbContextLogger), new ServiceCharacteristics(ServiceLifetime.Scoped) },
{ typeof(IAdHocMapper), new ServiceCharacteristics(ServiceLifetime.Scoped) },
{ typeof(ILazyLoader), new ServiceCharacteristics(ServiceLifetime.Transient) },
{ typeof(IParameterBindingFactory), new ServiceCharacteristics(ServiceLifetime.Singleton, multipleRegistrations: true) },
{ typeof(ITypeMappingSourcePlugin), new ServiceCharacteristics(ServiceLifetime.Singleton, multipleRegistrations: true) },
Expand Down Expand Up @@ -301,6 +302,7 @@ public virtual EntityFrameworkServicesBuilder TryAddCoreServices()
TryAdd<IQueryTranslationPostprocessorFactory, QueryTranslationPostprocessorFactory>();
TryAdd<INavigationExpansionExtensibilityHelper, NavigationExpansionExtensibilityHelper>();
TryAdd<IExceptionDetector, ExceptionDetector>();
TryAdd<IAdHocMapper, AdHocMapper>();

TryAdd(
p => p.GetService<IDbContextOptions>()?.FindExtension<CoreOptionsExtension>()?.DbContextLogger
Expand Down Expand Up @@ -426,7 +428,7 @@ public virtual EntityFrameworkServicesBuilder TryAdd
/// <returns>This builder, such that further calls can be chained.</returns>
public virtual EntityFrameworkServicesBuilder TryAdd
<TService, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TImplementation>(
Func<IServiceProvider, TImplementation> factory)
Func<IServiceProvider, TImplementation> factory)
where TService : class
where TImplementation : class, TService
=> TryAdd(typeof(TService), typeof(TImplementation), factory);
Expand Down
14 changes: 10 additions & 4 deletions src/EFCore/Infrastructure/ModelValidator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -237,8 +237,11 @@ protected virtual void ValidatePropertyMapping(
}

throw new InvalidOperationException(
CoreStrings.NavigationNotAdded(
entityType.DisplayName(), clrProperty.Name, propertyType.ShortDisplayName()));
Equals(model.FindAnnotation(CoreAnnotationNames.AdHocModel)?.Value, true)
? CoreStrings.NavigationNotAddedAdHoc(
entityType.DisplayName(), clrProperty.Name, propertyType.ShortDisplayName())
: CoreStrings.NavigationNotAdded(
entityType.DisplayName(), clrProperty.Name, propertyType.ShortDisplayName()));
}

// ReSharper restore CheckForReferenceEqualityInstead.3
Expand All @@ -254,8 +257,11 @@ protected virtual void ValidatePropertyMapping(
else
{
throw new InvalidOperationException(
CoreStrings.PropertyNotAdded(
entityType.DisplayName(), clrProperty.Name, propertyType.ShortDisplayName()));
Equals(model.FindAnnotation(CoreAnnotationNames.AdHocModel)?.Value, true)
? CoreStrings.PropertyNotAddedAdHoc(
entityType.DisplayName(), clrProperty.Name, propertyType.ShortDisplayName())
: CoreStrings.PropertyNotAdded(
entityType.DisplayName(), clrProperty.Name, propertyType.ShortDisplayName()));
}
}
}
Expand Down
Loading