Skip to content

Commit

Permalink
Add entity-splitting model building support
Browse files Browse the repository at this point in the history
Allow specifying different column names per table in TPT, TPC or entity splitting

Part of #620
Fixes #19811
  • Loading branch information
AndriySvyryd committed May 23, 2022
1 parent a8bf609 commit 339f161
Show file tree
Hide file tree
Showing 39 changed files with 2,484 additions and 366 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,25 @@ public override void Generate(IEntityType entityType, CSharpRuntimeAnnotationCod
annotations[RelationalAnnotationNames.SqlQuery] = entityType.GetSqlQuery();
annotations[RelationalAnnotationNames.FunctionName] = entityType.GetFunctionName();

if (annotations.TryGetAndRemove(
RelationalAnnotationNames.RelationalOverrides,
out Dictionary<StoreObjectIdentifier, IRelationalEntityTypeOverrides> overrides))
{
AddNamespace(typeof(Dictionary<StoreObjectIdentifier, IRelationalEntityTypeOverrides>), parameters.Namespaces);
AddNamespace(typeof(RuntimeRelationalEntityTypeOverrides), parameters.Namespaces);
AddNamespace(typeof(StoreObjectIdentifier), parameters.Namespaces);
var overridesVariable = Dependencies.CSharpHelper.Identifier("overrides", parameters.ScopeVariables, capitalize: false);
parameters.MainBuilder
.Append("var ").Append(overridesVariable).AppendLine(" = new Dictionary<StoreObjectIdentifier, IRelationalEntityTypeOverrides>();");

foreach (var (key, value) in overrides.OrderBy(pair => pair.Key.Name, StringComparer.Ordinal))
{
Create(value, key, overridesVariable, parameters);
}

GenerateSimpleAnnotation(RelationalAnnotationNames.RelationalOverrides, overridesVariable, parameters);
}

if (annotations.TryGetAndRemove(
RelationalAnnotationNames.Triggers,
out SortedDictionary<string, ITrigger> triggers))
Expand All @@ -346,6 +365,65 @@ public override void Generate(IEntityType entityType, CSharpRuntimeAnnotationCod

base.Generate(entityType, parameters);
}

private void Create(
IRelationalEntityTypeOverrides overrides,
StoreObjectIdentifier storeObject,
string overridesVariable,
CSharpRuntimeAnnotationCodeGeneratorParameters parameters)
{
var code = Dependencies.CSharpHelper;
var overrideVariable =
code.Identifier(parameters.TargetName + Capitalize(storeObject.Name), parameters.ScopeVariables, capitalize: false);
var mainBuilder = parameters.MainBuilder;
mainBuilder
.Append("var ").Append(overrideVariable).AppendLine(" = new RuntimeRelationalEntityTypeOverrides(").IncrementIndent()
.Append(parameters.TargetName).AppendLine(",");

AppendLiteral(storeObject, mainBuilder, code);
mainBuilder.AppendLine(");").DecrementIndent();

CreateAnnotations(
overrides,
GenerateOverrides,
parameters with { TargetName = overrideVariable });

mainBuilder.Append(overridesVariable).Append("[");
AppendLiteral(storeObject, mainBuilder, code);

mainBuilder
.Append("] = ")
.Append(overrideVariable).AppendLine(";");

static void AppendLiteral(StoreObjectIdentifier storeObject, IndentedStringBuilder builder, ICSharpHelper code)
{
builder.Append("StoreObjectIdentifier.");
switch (storeObject.StoreObjectType)
{
case StoreObjectType.Table:
builder
.Append("Table(").Append(code.Literal(storeObject.Name))
.Append(", ").Append(code.UnknownLiteral(storeObject.Schema)).Append(")");
break;
case StoreObjectType.View:
builder
.Append("View(").Append(code.Literal(storeObject.Name))
.Append(", ").Append(code.UnknownLiteral(storeObject.Schema)).Append(")");
break;
case StoreObjectType.SqlQuery:
builder
.Append("SqlQuery(").Append(code.Literal(storeObject.Name)).Append(")");
break;
case StoreObjectType.Function:
builder
.Append("DbFunction(").Append(code.Literal(storeObject.Name)).Append(")");
break;
default:
Check.DebugAssert(false, "Unexpected StoreObjectType: " + storeObject.StoreObjectType);
break;
}
}
}

private void Create(ITrigger trigger, string triggersVariable, CSharpRuntimeAnnotationCodeGeneratorParameters parameters)
{
Expand Down Expand Up @@ -410,16 +488,18 @@ public override void Generate(IProperty property, CSharpRuntimeAnnotationCodeGen

if (annotations.TryGetAndRemove(
RelationalAnnotationNames.RelationalOverrides,
out SortedDictionary<StoreObjectIdentifier, object> overrides))
out Dictionary<StoreObjectIdentifier, IRelationalPropertyOverrides> overrides))
{
parameters.Namespaces.Add(typeof(SortedDictionary<StoreObjectIdentifier, object>).Namespace!);
AddNamespace(typeof(Dictionary<StoreObjectIdentifier, IRelationalPropertyOverrides>), parameters.Namespaces);
AddNamespace(typeof(RuntimeRelationalPropertyOverrides), parameters.Namespaces);
AddNamespace(typeof(StoreObjectIdentifier), parameters.Namespaces);
var overridesVariable = Dependencies.CSharpHelper.Identifier("overrides", parameters.ScopeVariables, capitalize: false);
parameters.MainBuilder
.Append("var ").Append(overridesVariable).AppendLine(" = new SortedDictionary<StoreObjectIdentifier, object>();");
.Append("var ").Append(overridesVariable).AppendLine(" = new Dictionary<StoreObjectIdentifier, IRelationalPropertyOverrides>();");

foreach (var (key, value) in overrides)
foreach (var (key, value) in overrides.OrderBy(pair => pair.Key.Name, StringComparer.Ordinal))
{
Create((IRelationalPropertyOverrides)value, key, overridesVariable, parameters);
Create(value, key, overridesVariable, parameters);
}

GenerateSimpleAnnotation(RelationalAnnotationNames.RelationalOverrides, overridesVariable, parameters);
Expand All @@ -443,40 +523,51 @@ private void Create(
.Append("var ").Append(overrideVariable).AppendLine(" = new RuntimeRelationalPropertyOverrides(").IncrementIndent()
.Append(parameters.TargetName).AppendLine(",")
.Append(code.Literal(overrides.ColumnNameOverridden)).AppendLine(",")
.Append(code.UnknownLiteral(overrides.ColumnName)).AppendLine(");").DecrementIndent();
.Append(code.UnknownLiteral(overrides.ColumnName)).AppendLine(",");

AppendLiteral(storeObject, mainBuilder, code);
mainBuilder.AppendLine(");").DecrementIndent();

CreateAnnotations(
overrides,
GenerateOverrides,
parameters with { TargetName = overrideVariable });

mainBuilder.Append(overridesVariable).Append("[StoreObjectIdentifier.");

switch (storeObject.StoreObjectType)
{
case StoreObjectType.Table:
mainBuilder
.Append("Table(").Append(code.Literal(storeObject.Name))
.Append(", ").Append(code.UnknownLiteral(storeObject.Schema)).Append(")");
break;
case StoreObjectType.View:
mainBuilder
.Append("View(").Append(code.Literal(storeObject.Name))
.Append(", ").Append(code.UnknownLiteral(storeObject.Schema)).Append(")");
break;
case StoreObjectType.SqlQuery:
mainBuilder
.Append("SqlQuery(").Append(code.Literal(storeObject.Name)).Append(")");
break;
case StoreObjectType.Function:
mainBuilder
.Append("DbFunction(").Append(code.Literal(storeObject.Name)).Append(")");
break;
}
mainBuilder.Append(overridesVariable).Append("[");
AppendLiteral(storeObject, mainBuilder, code);

mainBuilder
.Append("] = ")
.Append(overrideVariable).AppendLine(";");

static void AppendLiteral(StoreObjectIdentifier storeObject, IndentedStringBuilder builder, ICSharpHelper code)
{
builder.Append("StoreObjectIdentifier.");
switch (storeObject.StoreObjectType)
{
case StoreObjectType.Table:
builder
.Append("Table(").Append(code.Literal(storeObject.Name))
.Append(", ").Append(code.UnknownLiteral(storeObject.Schema)).Append(")");
break;
case StoreObjectType.View:
builder
.Append("View(").Append(code.Literal(storeObject.Name))
.Append(", ").Append(code.UnknownLiteral(storeObject.Schema)).Append(")");
break;
case StoreObjectType.SqlQuery:
builder
.Append("SqlQuery(").Append(code.Literal(storeObject.Name)).Append(")");
break;
case StoreObjectType.Function:
builder
.Append("DbFunction(").Append(code.Literal(storeObject.Name)).Append(")");
break;
default:
Check.DebugAssert(false, "Unexpected StoreObjectType: " + storeObject.StoreObjectType);
break;
}
}
}

/// <summary>
Expand Down
Loading

0 comments on commit 339f161

Please sign in to comment.