entity-framework - 如何按照约定首先删除代码中外键字段的下划线

标签 entity-framework naming-conventions code-first entity-framework-6

我的项目中有多个类(包括 TPT)。每个 POCO 都有一个 BaseClass,它有一个 GUID(称为 GlobalKey)作为主键。

首先,我使用 DataAnnotations 创建正确的外键。但随后我在将相应的 GUID 与对象本身同步时遇到了问题。

现在我只想拥有一个虚拟导航属性,以便数据库中的 GUID 字段由 NamingConvention 创建。但字段名称总是添加一个下划线,后跟单词 GlobalKey (这是正确的)。当我想删除下划线时,我不想遍历 Fluent API 中的所有 POCO 来执行此操作:

// Remove underscore from Navigation-Field     
modelBuilder.Entity<Person>()
            .HasOptional(x => x.Address)
            .WithMany()
            .Map(a => a.MapKey("AddressGlobalKey"));

有什么想法可以通过覆盖约定来为所有 POCOS 做到这一点吗?

提前致谢。

安德烈亚斯

最佳答案

我终于通过编写自定义约定找到了这个问题的答案。此约定在 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.OnModelCreating 覆盖中的 DbContext 中,使用:

modelBuilder.Conventions.Add(new ForeignKeyNamingConvention());

关于entity-framework - 如何按照约定首先删除代码中外键字段的下划线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15684555/

相关文章:

c# - 如何使用 c# .net 核心 Entity Framework 执行连接

java - 我应该将字符串消息分配给极端情况下的某个变量并在方法结束时返回,还是立即返回?

c++ - 为什么 C++ 允许变量名和类名相同?

entity-framework-4 - 我如何创建一个包含外键的复合键,其中代码优先?

c# - 仅插入一次 EF 代码优先种子数据

entity-framework-4 - IDbSet和通过扩展方法公开Include方法

c# - Entity Framework 不一致 - 在这里工作,而不是那里

entity-framework - 如何在不使用更新数据库的情况下生成启用迁移的 EF6 数据库?

C# Entity Framework 自定义约束

rest - 用于(反)序列化 REST API 的请求和响应的模型的命名约定