В первую очередь влияет на именование столбцов внешнего ключа в EF-коде (CTP5)

У меня есть класс POCO, который имеет два односторонних унарных отношений с другим классом, оба класса совместно используют предка. Имена внешних ключей в сгенерированной схеме не отражают имена свойств. (Свойства MainContact и FinancialContact дают имена полей PersonId и PersonId1).

Как я могу повлиять на создание схемы для создания имен столбцов базы данных, которые соответствуют именам свойств?

Модель выглядит следующим образом:

The class model

Код выглядит следующим образом:

public class CustomerContext: DbContext
{
   public DbSet<Organisation> Organisations { get; set; }
   public DbSet<Person> Persons { get; set; }

   protected override void OnModelCreating(ModelBuilder builder)
   {
      DbDatabase.SetInitializer(new DropCreateDatabaseAlways<CustomerContext>());
   }
}

public abstract class Customer
{
   public int Id { get; set; }
   public string Name { get; set; }
}

public class Person : Customer
{
   public string Email { get; set; }
}

public class Organisation : Customer
{
   public Person FinancialContact { get; set; }
   public Person MainContact { get; set; }
}

Схема выглядит следующим образом: enter image description here

Ответ от druttka


druttka ответ ниже выполнил эту работу, и приятно узнать, что это ошибка CTP5, которая стоит за этим. EF также нуждается в каскадном поведении, которое должно быть указано, и я использовал свободный API для этого, следуя примеру в ссылке, приведенной druttka. Еще более хорошее чтение из Morteza Manavi здесь.

Теперь это код:

public class CustomerContext : DbContext
{
   public DbSet<Organisation> Organisations { get; set; }
   public DbSet<Person> Persons { get; set; }

   protected override void OnModelCreating(ModelBuilder builder)
   {
      DbDatabase.SetInitializer(new DropCreateDatabaseAlways<CustomerContext>());

      builder.Entity<Organisation>()
         .HasRequired(p => p.MainContact)
         .WithMany()
         .HasForeignKey(p => p.MainContactId)
         .WillCascadeOnDelete(false);
      builder.Entity<Organisation>()
         .Property(p => p.MainContactId)
         .HasColumnName("MainContact");

      builder.Entity<Organisation>()
         .HasRequired(p => p.FinancialContact)
         .WithMany()
         .HasForeignKey(p => p.FinancialContactId)
         .WillCascadeOnDelete(false);
      builder.Entity<Organisation>()
         .Property(p => p.FinancialContactId)
         .HasColumnName("FinancialContact");
   }
}

public abstract class Customer
{
   public int Id { get; set; }
   public string Name { get; set; }
}

public class Person : Customer
{
   public string Email { get; set; }
}

public class Organisation : Customer
{
   public Person FinancialContact { get; set; }
   public int FinancialContactId { get; set; }

   public Person MainContact { get; set; }
   public int MainContactId { get; set; }
}

Что теперь дает гораздо более подходящую базу данных: enter image description here

Ответы

Ответ 1

EF Code First использует, по умолчанию, соглашение по конфигурации. Однако вы можете установить явные альтернативы, переопределив DbContent.OnModelCreating. Много примеров здесь, любезно предоставлено ScottGu.

ИЗМЕНИТЬ

Итак, в CTP5 MapSingleType ушел, как описано здесь. Следующее работает для простых свойств строки, но не для отношений "Организация с человеком". Мне любопытно и планировать продолжать смотреть на него, но тем временем, может быть, это поможет вам начать, или кто-то еще сможет ответить.

public class Person : Customer
{
    [Column(Name="EmailAddress")]
    public string Email { get; set; }
}

РЕДАКТИРОВАТЬ 2

Хорошо, это получается. Найден ответ здесь. Отказ от ответственности: я только подтвердил, что схема базы данных создается, как ожидалось. Я не тестировал, что данные для посева или дальнейшие операции CRUD работают, как ожидалось.

public class Organisation : Customer
{
    [Column(Name = "FinancialContact")]
    public int? FinancialContactId { get; set; }
    [ForeignKey("FinancialContactId")]
    public Person FinancialContact { get; set; }
    [Column(Name = "MainContact")]
    public int? MainContactId { get; set; }
    [ForeignKey("MainContactId")]
    public Person MainContact { get; set; }
}