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
Move EntityTypeBuilder properties on store object builders to explicit implementation
Change TableValuedFunctionBuilder to follow the pattern
Introduce IReadOnlyStoreObjectDictionary to abstract table-specific configuration storage
Rename GetColumnBaseName to GetColumnName

Part of #620
Fixes #19811
  • Loading branch information
AndriySvyryd committed Jun 7, 2022
1 parent f43f454 commit a95d1f0
Show file tree
Hide file tree
Showing 109 changed files with 8,295 additions and 3,044 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ private void GenerateKeyAttribute(IProperty property)

private void GenerateColumnAttribute(IProperty property)
{
var columnName = property.GetColumnBaseName();
var columnName = property.GetColumnName();
var columnType = property.GetConfiguredColumnType();

var delimitedColumnName = columnName != null && columnName != property.Name ? _code.Literal(columnName) : null;
Expand Down
3 changes: 2 additions & 1 deletion src/EFCore.Relational/Design/AnnotationCodeGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public class AnnotationCodeGenerator : IAnnotationCodeGenerator
RelationalAnnotationNames.Triggers,
RelationalAnnotationNames.Sequences,
RelationalAnnotationNames.DbFunctions,
RelationalAnnotationNames.MappingFragments,
RelationalAnnotationNames.RelationalOverrides
};

Expand Down Expand Up @@ -161,7 +162,7 @@ public virtual void RemoveAnnotationsHandledByConventions(
IProperty property,
IDictionary<string, IAnnotation> annotations)
{
var columnName = property.GetColumnBaseName();
var columnName = property.GetColumnName();
if (columnName == property.Name)
{
annotations.Remove(RelationalAnnotationNames.ColumnName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,24 @@ public override void Generate(IEntityType entityType, CSharpRuntimeAnnotationCod
annotations[RelationalAnnotationNames.SqlQuery] = entityType.GetSqlQuery();
annotations[RelationalAnnotationNames.FunctionName] = entityType.GetFunctionName();

if (annotations.TryGetAndRemove(
RelationalAnnotationNames.MappingFragments,
out IReadOnlyStoreObjectDictionary<IEntityTypeMappingFragment> fragments))
{
AddNamespace(typeof(StoreObjectDictionary<RuntimeEntityTypeMappingFragment>), parameters.Namespaces);
AddNamespace(typeof(StoreObjectIdentifier), parameters.Namespaces);
var fragmentsVariable = Dependencies.CSharpHelper.Identifier("fragments", parameters.ScopeVariables, capitalize: false);
parameters.MainBuilder
.Append("var ").Append(fragmentsVariable).AppendLine(" = new StoreObjectDictionary<RuntimeEntityTypeMappingFragment>();");

foreach (var fragment in fragments.GetValues())
{
Create(fragment, fragmentsVariable, parameters);
}

GenerateSimpleAnnotation(RelationalAnnotationNames.MappingFragments, fragmentsVariable, parameters);
}

if (annotations.TryGetAndRemove(
RelationalAnnotationNames.Triggers,
out SortedDictionary<string, ITrigger> triggers))
Expand All @@ -347,6 +365,37 @@ public override void Generate(IEntityType entityType, CSharpRuntimeAnnotationCod
base.Generate(entityType, parameters);
}

private void Create(
IEntityTypeMappingFragment fragment,
string fragmentsVariable,
CSharpRuntimeAnnotationCodeGeneratorParameters parameters)
{
var storeObject = fragment.StoreObject;
var code = Dependencies.CSharpHelper;
var overrideVariable =
code.Identifier(storeObject.Name + "Fragment", parameters.ScopeVariables, capitalize: false);
var mainBuilder = parameters.MainBuilder;
mainBuilder
.Append("var ").Append(overrideVariable).AppendLine(" = new RuntimeEntityTypeMappingFragment(").IncrementIndent()
.Append(parameters.TargetName).AppendLine(",");

AppendLiteral(storeObject, mainBuilder, code);
mainBuilder.AppendLine(",")
.Append(code.Literal(fragment.IsTableExcludedFromMigrations)).AppendLine(");").DecrementIndent();

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

mainBuilder.Append(fragmentsVariable).Append(".Add(");
AppendLiteral(storeObject, mainBuilder, code);

mainBuilder
.Append(", ")
.Append(overrideVariable).AppendLine(");");
}

private void Create(ITrigger trigger, string triggersVariable, CSharpRuntimeAnnotationCodeGeneratorParameters parameters)
{
var code = Dependencies.CSharpHelper;
Expand Down Expand Up @@ -410,16 +459,17 @@ public override void Generate(IProperty property, CSharpRuntimeAnnotationCodeGen

if (annotations.TryGetAndRemove(
RelationalAnnotationNames.RelationalOverrides,
out SortedDictionary<StoreObjectIdentifier, object> overrides))
out IReadOnlyStoreObjectDictionary<IRelationalPropertyOverrides> tableOverrides))
{
parameters.Namespaces.Add(typeof(SortedDictionary<StoreObjectIdentifier, object>).Namespace!);
AddNamespace(typeof(StoreObjectDictionary<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 StoreObjectDictionary<RuntimeRelationalPropertyOverrides>();");

foreach (var (key, value) in overrides)
foreach (var overrides in tableOverrides.GetValues())
{
Create((IRelationalPropertyOverrides)value, key, overridesVariable, parameters);
Create(overrides, overridesVariable, parameters);
}

GenerateSimpleAnnotation(RelationalAnnotationNames.RelationalOverrides, overridesVariable, parameters);
Expand All @@ -431,17 +481,20 @@ public override void Generate(IProperty property, CSharpRuntimeAnnotationCodeGen

private void Create(
IRelationalPropertyOverrides overrides,
StoreObjectIdentifier storeObject,
string overridesVariable,
CSharpRuntimeAnnotationCodeGeneratorParameters parameters)
{
var storeObject = overrides.StoreObject;
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 RuntimeRelationalPropertyOverrides(").IncrementIndent()
.Append(parameters.TargetName).AppendLine(",")
.Append(parameters.TargetName).AppendLine(",");
AppendLiteral(storeObject, mainBuilder, code);

mainBuilder.AppendLine(",")
.Append(code.Literal(overrides.ColumnNameOverridden)).AppendLine(",")
.Append(code.UnknownLiteral(overrides.ColumnName)).AppendLine(");").DecrementIndent();

Expand All @@ -450,33 +503,12 @@ private void Create(
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(".Add(");
AppendLiteral(storeObject, mainBuilder, code);

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

/// <summary>
Expand Down Expand Up @@ -553,4 +585,33 @@ private static string Capitalize(string @string)
return char.ToUpperInvariant(@string[0]) + @string[1..];
}
}

private 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;
}
}
}
Loading

0 comments on commit a95d1f0

Please sign in to comment.