如何对自有类型使用自定义名称约定?
How to use custom name convention with owned types?
public class ProcessInitialization
{
public Guid CorrelationId { get; set; }
public MyProcessContext ProcessContext { get; set; }
}
public class MyProcessContext
{
public int? ProcessId { get; set; }
}
没有使用我的约定,我得到了
SELECT `process`.`CorrelationId`
FROM `ProcessInitialization` AS `process`
WHERE `process`.`ProcessContext_ProcessId` = 8
我的惯例是 snake_case
从 PascalCase
:
public static void SetSimpleUnderscoreTableNameConvention(this ModelBuilder modelBuilder,
bool preserveAcronyms,
IDictionary<string, string> propertyMap = null,
IDictionary<string, string> entityMap = null
)
{
var propMap = propertyMap ?? new Dictionary<string, string>();
var entMap = entityMap ?? new Dictionary<string, string>();
foreach (var entity in modelBuilder.Model.GetEntityTypes())
{
foreach (var prop in entity.GetProperties())
{
if (propMap.ContainsKey(prop.Name))
{
prop.Relational().ColumnName = propMap[prop.Name];
}
else
{
var underscoredProp = AddUndercoresToSentence(prop.Name, preserveAcronyms);
prop.Relational().ColumnName = underscoredProp.ToLowerInvariant();
}
}
var entName = entity.DisplayName();
if (entMap.ContainsKey(entName))
{
entity.Relational().TableName = entMap[entName];
}
else
{
var underscored = AddUndercoresToSentence(entity.DisplayName(), preserveAcronyms);
entity.Relational().TableName = underscored.ToLowerInvariant();
}
}
}
使用它查询无效:
SELECT `process`.`correlation_id`
FROM `process`
LEFT JOIN `process_initialization._process_context#_my_process_context` AS `process.ProcessContext` ON `process`.`correlation_id` = `process.ProcessContext`.`process_initialization_correlation_id`
WHERE `process.ProcessContext`.`process_id` = 8
看来我不需要将我的转换应用于某些 entity
:
var underscored = AddUndercoresToSentence(entity.DisplayName(), preserveAcronyms);
if (underscored.Contains("#")) // any other way to understand it is special?
continue;
entity.Relational().TableName = underscored.ToLowerInvariant();
之后我得到:
The keys {'ProcessInitializationCorrelationId'} on 'ProcessInitialization.ProcessContext#MyProcessContext' and {'CorrelationId'} on 'ProcessInitialization' are both mapped to 'process_initialization.PK_process_initialization' but with different columns ({'process_initialization_correlation_id'} and {'correlation_id'}).
拥有的类型需要特殊处理。
首先,您使用IEntityType.IsOwned()
方法识别它们。
然后,当拥有实体类型时,您应该跳过 table 名称映射(因为它们与根所有者实体共享相同的 table)。拥有的类型还具有应该跳过的阴影 PK 属性,对于其他属性,您应该从根所有者到拥有的类型的路径构建列名称。所有者信息可通过 IEntityType
.
的 DefiningEntityType
和 DefiningNavigationName
属性访问
将所有这些应用到您的代码中:
foreach (var entity in modelBuilder.Model.GetEntityTypes())
{
foreach (var prop in entity.GetProperties())
{
if (entity.IsOwned() && prop.IsPrimaryKey()) continue;
IEntityType propOwner = entity;
string propName = prop.Name, columnName = null;
do
{
if (!propMap.TryGetValue(propName, out var name))
name = AddUndercoresToSentence(propName, preserveAcronyms).ToLowerInvariant();
columnName = columnName == null ? name : name + "_" + columnName;
propName = propOwner.DefiningNavigationName;
propOwner = propOwner.DefiningEntityType;
}
while (propName != null);
prop.Relational().ColumnName = columnName;
}
if (entity.IsOwned()) continue;
var entName = entity.DisplayName();
if (!entMap.TryGetValue(entName, out var tableName))
tableName = AddUndercoresToSentence(entName, preserveAcronyms).ToLowerInvariant();
entity.Relational().TableName = tableName;
}
public class ProcessInitialization
{
public Guid CorrelationId { get; set; }
public MyProcessContext ProcessContext { get; set; }
}
public class MyProcessContext
{
public int? ProcessId { get; set; }
}
没有使用我的约定,我得到了
SELECT `process`.`CorrelationId`
FROM `ProcessInitialization` AS `process`
WHERE `process`.`ProcessContext_ProcessId` = 8
我的惯例是 snake_case
从 PascalCase
:
public static void SetSimpleUnderscoreTableNameConvention(this ModelBuilder modelBuilder,
bool preserveAcronyms,
IDictionary<string, string> propertyMap = null,
IDictionary<string, string> entityMap = null
)
{
var propMap = propertyMap ?? new Dictionary<string, string>();
var entMap = entityMap ?? new Dictionary<string, string>();
foreach (var entity in modelBuilder.Model.GetEntityTypes())
{
foreach (var prop in entity.GetProperties())
{
if (propMap.ContainsKey(prop.Name))
{
prop.Relational().ColumnName = propMap[prop.Name];
}
else
{
var underscoredProp = AddUndercoresToSentence(prop.Name, preserveAcronyms);
prop.Relational().ColumnName = underscoredProp.ToLowerInvariant();
}
}
var entName = entity.DisplayName();
if (entMap.ContainsKey(entName))
{
entity.Relational().TableName = entMap[entName];
}
else
{
var underscored = AddUndercoresToSentence(entity.DisplayName(), preserveAcronyms);
entity.Relational().TableName = underscored.ToLowerInvariant();
}
}
}
使用它查询无效:
SELECT `process`.`correlation_id`
FROM `process`
LEFT JOIN `process_initialization._process_context#_my_process_context` AS `process.ProcessContext` ON `process`.`correlation_id` = `process.ProcessContext`.`process_initialization_correlation_id`
WHERE `process.ProcessContext`.`process_id` = 8
看来我不需要将我的转换应用于某些 entity
:
var underscored = AddUndercoresToSentence(entity.DisplayName(), preserveAcronyms);
if (underscored.Contains("#")) // any other way to understand it is special?
continue;
entity.Relational().TableName = underscored.ToLowerInvariant();
之后我得到:
The keys {'ProcessInitializationCorrelationId'} on 'ProcessInitialization.ProcessContext#MyProcessContext' and {'CorrelationId'} on 'ProcessInitialization' are both mapped to 'process_initialization.PK_process_initialization' but with different columns ({'process_initialization_correlation_id'} and {'correlation_id'}).
拥有的类型需要特殊处理。
首先,您使用IEntityType.IsOwned()
方法识别它们。
然后,当拥有实体类型时,您应该跳过 table 名称映射(因为它们与根所有者实体共享相同的 table)。拥有的类型还具有应该跳过的阴影 PK 属性,对于其他属性,您应该从根所有者到拥有的类型的路径构建列名称。所有者信息可通过 IEntityType
.
DefiningEntityType
和 DefiningNavigationName
属性访问
将所有这些应用到您的代码中:
foreach (var entity in modelBuilder.Model.GetEntityTypes())
{
foreach (var prop in entity.GetProperties())
{
if (entity.IsOwned() && prop.IsPrimaryKey()) continue;
IEntityType propOwner = entity;
string propName = prop.Name, columnName = null;
do
{
if (!propMap.TryGetValue(propName, out var name))
name = AddUndercoresToSentence(propName, preserveAcronyms).ToLowerInvariant();
columnName = columnName == null ? name : name + "_" + columnName;
propName = propOwner.DefiningNavigationName;
propOwner = propOwner.DefiningEntityType;
}
while (propName != null);
prop.Relational().ColumnName = columnName;
}
if (entity.IsOwned()) continue;
var entName = entity.DisplayName();
if (!entMap.TryGetValue(entName, out var tableName))
tableName = AddUndercoresToSentence(entName, preserveAcronyms).ToLowerInvariant();
entity.Relational().TableName = tableName;
}