Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change the naming convention of Many-to-Many table relationships?

How can I go about changing the naming convention of the auto-generated many-to-many table?

Assume I have two classes:

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; }
}

By Default, this will create a table called UserRoles.

I can change the name of that one table to UsersInRoles, for example, by using the following in the OnModelCreating override of my DbContext:

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

However, what I really want to do is change the naming convention so that by default, all auto-generated many-to-many tables use this new convention. I cannot figure out how to do that, or if it's even possible. I do not like having to specify 9 lines of extra code every time I specify one of these relationships.

I am currently using EF version 6.0.0-rc1.

like image 952
Nathan A Avatar asked Sep 28 '13 16:09

Nathan A


Video Answer


1 Answers

The ability to control relationships was removed from the basic conventions API before release because it wasn't in a usable state. You can access all of the properties and tables in the model through model based conventions. An overview of model based conventions is available here: http://msdn.microsoft.com/en-US/data/dn469439

This solution involves a little more digging around in the metadata API, EntitySet is the correct type for this scenario

This convention should rename the generated relation table:

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";
            }
        }
    }
like image 159
lukew Avatar answered Oct 19 '22 04:10

lukew