カスタム規則を作成することで、最終的にこれに対する答えを見つけました。この規則は 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());