如何更改多对多表关系的命名约定?

时间:2013-09-28 16:41:21

标签: entity-framework ef-code-first entity-framework-6

如何更改自动生成的多对多表的命名约定?

假设我有两个班级:

public class User
{
    public int UserId { get; set; }
    public virtual List<Role> Roles { get; set; }
}

public class Role
{
    public int RoleId { get; set; }
    public virtual List<User> Users { get; set; }
}

默认情况下,这将创建一个名为 UserRoles 的表。

我可以将一个表的名称更改为 UsersInRoles ,例如,在我的DbContext的OnModelCreating覆盖中使用以下内容:

modelBuilder.Entity<User>()
    .HasMany(p => p.Roles)
    .WithMany(p => p.Users)
    .Map(mc =>
    {
        mc.MapLeftKey("UserId");
        mc.MapRightKey("RoleId");
        mc.ToTable("UsersInRoles");
    });

但是,我真正想要做的是更改命名约定,以便默认情况下,所有自动生成的多对多表都使用此新约定。我无法弄清楚如何做到这一点,或者甚至可能。我不希望每次指定其中一个关系时都必须指定9行额外代码。

我目前正在使用EF版本6.0.0-rc1。

1 个答案:

答案 0 :(得分:5)

在发布之前,已从基本约定API中删除了控制关系的能力,因为它不处于可用状态。您可以通过基于模型的约定访问模型中的所有属性和表。此处提供了基于模型的约定的概述:http://msdn.microsoft.com/en-US/data/dn469439

此解决方案涉及在元数据API中进行更多挖掘,EntitySet是此方案的正确类型

此约定应重命名生成的关系表:

public class MyConvention : IStoreModelConvention<EntitySet>
{
    public void Apply(EntitySet set, DbModel model)
    {
        var properties = set.ElementType.Properties;
        if (properties.Count == 2)
        {
            var relationEnds = new List<string>();
            int i = 0;
            foreach (var metadataProperty in properties)
            {
                if (metadataProperty.Name.EndsWith("_ID"))
                {
                    var name = metadataProperty.Name;
                    relationEnds.Add(name.Substring(0, name.Length - 3));
                    i++;
                }
            }
            if (relationEnds.Count == 2)
            {
                set.Table = relationEnds.ElementAt(0) + "_" + relationEnds.ElementAt(1) + "_RelationTable";
            }
        }
    }