我终于找到了一个答案,通过编写一个自定义约定。该惯例适用于EF 6.0 RC1(上周的代码),所以我认为在EF 6.0发布后它可能会继续工作。
使用此方法,标准EF约定标识独立关联(IAs),然后为外键字段创建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());
你不能这样做 - 但。有一个[可定制的代码优先开发功能的约定](http://msdn.microsoft.com/en-us/data/jj819164.aspx)正在为EF 6.0工作,但现在 - 你必须处理这个你自己,手动... –
我实际上使用EF6 alpha 2.是否有可能以这种方式使用它? –
[查看此博客文章](http://blog.3d-logic.com/2013/03/24/my-first-encounter-with-custom-conventions-in-entity-framework-6/) - this同事似乎在做一些类似于你想要的事情。 –