2013-09-28 3 views
5

Как я могу изменить правило именования автоматически созданной таблицы «многие-ко-многим»?Как изменить соглашение об именах отношений «Многие-ко-многим»?

Предположим, у меня есть два класса:

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, например, с помощью следующих в OnModelCreating переопределение моего DbContext:

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.

+0

Из любопытства, почему вы действительно хотите это сделать? Кодирование по соглашению теряет все свое очарование, когда вы продолжаете иметь разные. –

+0

Вы можете взглянуть на [Пользовательские соглашения] (http://msdn.microsoft.com/en-us/data/jj819164.aspx). –

+0

@TonyHopkinson. В моем реальном сценарии я пишу фреймворк, который изменяет все имена таблиц с префиксом на основе их «компонентного» местоположения (например, Core, HR, Finance и т. Д.). В то время как я смог написать catch-all для стандартного переименования таблицы, он не работал с этими таблицами «многие-ко-многим», и я не могу понять, как это сделать. Что касается моего примера, я давно использовал это соглашение и хотел бы придерживаться его. –

ответ

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"; 
      } 
     } 
    } 
+0

Я играл с этим, но обнаружил, что соглашение EntityType не позволяет мне переименовывать таблицы. Свойство Set Name является внутренним. И снова я застрял в том, что мне нужно переименовать каждую таблицу вручную. –

+0

Вышеупомянутая конвенция решает вашу проблему или есть что-то еще, что вам нужно? – lukew

+0

Нет, это прекрасно! Не могу сказать, что я почти так же знаком с EDM, как и должен, но это отлично работает. Благодаря! –