通过编写自定义约定,我终于找到了答案。这个约定在 EF 6.0 RC1(上周的代码)中有效,所以我认为在 EF 6.0 发布后它可能会继续有效。
使用这种方法,标准 EF 约定识别独立关联 (IA),然后为外键字段创建 EdmProperty。然后这个约定出现并重命名外键字段。
/// <summary>
/// Provides a convention for fixing the independent association (IA) foreign key column names.
/// </summary>
public class ForeignKeyNamingConvention : IStoreModelConvention<AssociationType>
{
public void Apply(AssociationType association, DbModel model)
{
// Identify a ForeignKey properties (including IAs)
if (association.IsForeignKey)
{
// rename FK columns
var constraint = association.Constraint;
if (DoPropertiesHaveDefaultNames(constraint.FromProperties, constraint.ToRole.Name, constraint.ToProperties))
{
NormalizeForeignKeyProperties(constraint.FromProperties);
}
if (DoPropertiesHaveDefaultNames(constraint.ToProperties, constraint.FromRole.Name, constraint.FromProperties))
{
NormalizeForeignKeyProperties(constraint.ToProperties);
}
}
}
private bool DoPropertiesHaveDefaultNames(ReadOnlyMetadataCollection<EdmProperty> properties, string roleName, ReadOnlyMetadataCollection<EdmProperty> otherEndProperties)
{
if (properties.Count != otherEndProperties.Count)
{
return false;
}
for (int i = 0; i < properties.Count; ++i)
{
if (!properties[i].Name.EndsWith("_" + otherEndProperties[i].Name))
{
return false;
}
}
return true;
}
private void NormalizeForeignKeyProperties(ReadOnlyMetadataCollection<EdmProperty> properties)
{
for (int i = 0; i < properties.Count; ++i)
{
string defaultPropertyName = properties[i].Name;
int ichUnderscore = defaultPropertyName.IndexOf('_');
if (ichUnderscore <= 0)
{
continue;
}
string navigationPropertyName = defaultPropertyName.Substring(0, ichUnderscore);
string targetKey = defaultPropertyName.Substring(ichUnderscore + 1);
string newPropertyName;
if (targetKey.StartsWith(navigationPropertyName))
{
newPropertyName = targetKey;
}
else
{
newPropertyName = navigationPropertyName + targetKey;
}
properties[i].Name = newPropertyName;
}
}
}
请注意,使用以下命令将约定添加到您DbContext
的DbContext.OnModelCreating
覆盖中:
modelBuilder.Conventions.Add(new ForeignKeyNamingConvention());