Skip to content

Commit f9c5dc6

Browse files
committed
Metadata: Bring back SqlServerDbFunctionConvention
Resolve #20182
1 parent e4884bb commit f9c5dc6

File tree

3 files changed

+51
-55
lines changed

3 files changed

+51
-55
lines changed

src/EFCore.SqlServer/Metadata/Conventions/SqlServerConventionSetBuilder.cs

+2
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ public override ConventionSet CreateConventionSet()
9393
ReplaceConvention(conventionSet.ModelFinalizingConventions,
9494
(SharedTableConvention)new SqlServerSharedTableConvention(Dependencies, RelationalDependencies));
9595

96+
conventionSet.ModelFinalizingConventions.Add(new SqlServerDbFunctionConvention(Dependencies, RelationalDependencies));
97+
9698
return conventionSet;
9799
}
98100

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using JetBrains.Annotations;
5+
using Microsoft.EntityFrameworkCore.Metadata.Builders;
6+
using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure;
7+
using Microsoft.EntityFrameworkCore.Utilities;
8+
9+
// ReSharper disable once CheckNamespace
10+
namespace Microsoft.EntityFrameworkCore.Metadata.Conventions
11+
{
12+
/// <summary>
13+
/// A convention that ensures that <see cref="IDbFunction.Schema"/> is populated for database functions which are not built-in.
14+
/// </summary>
15+
public class SqlServerDbFunctionConvention : IModelFinalizingConvention
16+
{
17+
/// <summary>
18+
/// Creates a new instance of <see cref="SqlServerDbFunctionConvention" />.
19+
/// </summary>
20+
/// <param name="dependencies"> Parameter object containing dependencies for this convention. </param>
21+
/// <param name="relationalDependencies"> Parameter object containing relational dependencies for this convention. </param>
22+
public SqlServerDbFunctionConvention(
23+
[NotNull] ProviderConventionSetBuilderDependencies dependencies,
24+
[NotNull] RelationalConventionSetBuilderDependencies relationalDependencies)
25+
{
26+
Check.NotNull(dependencies, nameof(dependencies));
27+
Check.NotNull(relationalDependencies, nameof(relationalDependencies));
28+
29+
Dependencies = dependencies;
30+
}
31+
32+
/// <summary>
33+
/// Parameter object containing service dependencies.
34+
/// </summary>
35+
protected virtual ProviderConventionSetBuilderDependencies Dependencies { get; }
36+
37+
/// <inheritdoc />
38+
public virtual void ProcessModelFinalizing(IConventionModelBuilder modelBuilder, IConventionContext<IConventionModelBuilder> context)
39+
{
40+
foreach (var dbFunction in modelBuilder.Metadata.GetDbFunctions())
41+
{
42+
if (string.IsNullOrEmpty(dbFunction.Schema))
43+
{
44+
dbFunction.SetSchema("dbo");
45+
}
46+
}
47+
}
48+
}
49+
}

src/EFCore.SqlServer/Query/Internal/SqlServerQuerySqlGenerator.cs

-55
Original file line numberDiff line numberDiff line change
@@ -99,60 +99,5 @@ protected override void GenerateLimitOffset(SelectExpression selectExpression)
9999
}
100100
}
101101
}
102-
103-
/// <summary>
104-
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
105-
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
106-
/// any release. You should only use it directly in your code with extreme caution and knowing that
107-
/// doing so can result in application failures when updating to a new Entity Framework Core release.
108-
/// </summary>
109-
protected override Expression VisitSqlFunction(SqlFunctionExpression sqlFunctionExpression)
110-
{
111-
Check.NotNull(sqlFunctionExpression, nameof(sqlFunctionExpression));
112-
113-
if (!sqlFunctionExpression.IsBuiltIn
114-
&& string.IsNullOrEmpty(sqlFunctionExpression.Schema))
115-
{
116-
sqlFunctionExpression = sqlFunctionExpression.IsNiladic
117-
? new SqlFunctionExpression(
118-
schema: "dbo",
119-
sqlFunctionExpression.Name,
120-
sqlFunctionExpression.IsNullable,
121-
sqlFunctionExpression.Type,
122-
sqlFunctionExpression.TypeMapping)
123-
: new SqlFunctionExpression(
124-
schema: "dbo",
125-
sqlFunctionExpression.Name,
126-
sqlFunctionExpression.Arguments,
127-
sqlFunctionExpression.IsNullable,
128-
sqlFunctionExpression.ArgumentsPropagateNullability,
129-
sqlFunctionExpression.Type,
130-
sqlFunctionExpression.TypeMapping);
131-
}
132-
133-
return base.VisitSqlFunction(sqlFunctionExpression);
134-
}
135-
136-
/// <summary>
137-
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
138-
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
139-
/// any release. You should only use it directly in your code with extreme caution and knowing that
140-
/// doing so can result in application failures when updating to a new Entity Framework Core release.
141-
/// </summary>
142-
protected override Expression VisitTableValuedFunction(TableValuedFunctionExpression tableValuedFunctionExpression)
143-
{
144-
Check.NotNull(tableValuedFunctionExpression, nameof(tableValuedFunctionExpression));
145-
146-
if (string.IsNullOrEmpty(tableValuedFunctionExpression.Schema))
147-
{
148-
tableValuedFunctionExpression = new TableValuedFunctionExpression(
149-
tableValuedFunctionExpression.Alias,
150-
schema: "dbo",
151-
tableValuedFunctionExpression.Name,
152-
tableValuedFunctionExpression.Arguments);
153-
}
154-
155-
return base.VisitTableValuedFunction(tableValuedFunctionExpression);
156-
}
157102
}
158103
}

0 commit comments

Comments
 (0)