Поиск…


замечания

Существует два общих способа указания HOW Entity Framework сопоставляет классы POCO с таблицами, столбцами базы данных и т. Д .: аннотации данных и свободный API .

Хотя аннотации данных являются простыми для чтения и понимания, у них отсутствуют определенные функции, такие как указание поведения «Cascade on Delete» для объекта. Fluent API, с другой стороны, немного сложнее в использовании, но обеспечивает гораздо более сложный набор функций.

Модели отображения

EntityFramewok Fluent API - это мощный и элегантный способ сопоставления ваших кодовых моделей домена с базой данных. Это также можно использовать с кодом сначала с существующей базой данных . У вас есть два варианта при использовании Fluent API : вы можете напрямую сопоставлять свои модели с методом OnModelCreating или создавать классы сопоставления, которые наследуются от EntityTypeConfiguration, а затем добавлять эти модели в modelBuilder по методу OnModelCreating . Второй вариант, который я предпочитаю, и я покажу пример этого.

Шаг первый: создайте модель.

public class Employee
{
    public int Id { get; set; }
    public string Surname { get; set; }    
    public string FirstName { get; set; }    
    public string LastName { get; set; }        
    public short Age { get; set; }    
    public decimal MonthlySalary { get; set; }
        
    public string FullName
    {
        get
        {
            return $"{Surname} {FirstName} {LastName}";
        }
    }
}

Шаг второй: создать класс сопоставления

public class EmployeeMap
    : EntityTypeConfiguration<Employee>
{
    public EmployeeMap()
    {
        // Primary key
        this.HasKey(m => m.Id);
        
        this.Property(m => m.Id)
            .HasColumnType("int")
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
            
        // Properties
        this.Property(m => m.Surname)
            .HasMaxLength(50);
            
        this.Property(m => m.FirstName)
            .IsRequired()
            .HasMaxLength(50);
            
        this.Property(m => m.LastName)
            .HasMaxLength(50);
            
        this.Property(m => m.Age)
            .HasColumnType("smallint");
            
        this.Property(m => m.MonthlySalary)
            .HasColumnType("number")
            .HasPrecision(14, 5);
            
        this.Ignore(m => m.FullName);
        
        // Table & column mappings
        this.ToTable("TABLE_NAME", "SCHEMA_NAME");
        this.Property(m => m.Id).HasColumnName("ID");
        this.Property(m => m.Surname).HasColumnName("SURNAME");
        this.Property(m => m.FirstName).HasColumnName("FIRST_NAME");
        this.Property(m => m.LastName).HasColumnName("LAST_NAME");
        this.Property(m => m.Age).HasColumnName("AGE");
        this.Property(m => m.MonthlySalary).HasColumnName("MONTHLY_SALARY");
    }
}

Объясним отображения:

  • HasKey - определяет первичный ключ. Также можно использовать составные первичные ключи . Например: this.HasKey (m => new {m.DepartmentId, m.PositionId}) .
  • Свойство - позволяет нам настраивать свойства модели.
  • HasColumnType - указать тип столбца уровня базы данных. Обратите внимание, что это может быть разным для разных баз данных, таких как Oracle и MS SQL.
  • HasDatabaseGeneratedOption - указывает, вычисляется ли свойство на уровне базы данных. Числовые ПК имеют значение DatabaseGeneratedOption.Identity по умолчанию, вы должны указать DatabaseGeneratedOption.None, если вы не хотите, чтобы это было так.
  • HasMaxLength - ограничивает длину строки.
  • IsRequired - маркирует свойство как требуемое.
  • HasPrecision - позволяет указать точность для десятичных знаков.
  • Игнорировать - Игнорировать свойство полностью и не отображать его в базе данных. Мы проигнорировали FullName, потому что этот столбец не нужен в нашей таблице.
  • ToTable - указать имя таблицы и имя схемы (необязательно) для модели.
  • HasColumnName - связывает свойство с именем столбца. Это не требуется, если имена свойств и имена столбцов идентичны.

Шаг третий: добавьте класс сопоставления в конфигурации.

Нам нужно сказать EntityFramework, чтобы использовать наш класс mapper. Для этого нам нужно добавить его в modelBuilder.Configurations on OnModelCreating :

public class DbContext()
    : base("Name=DbContext")
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new EmployeeMap());
    }
}

И это все. Мы все готовы идти.

Основной ключ

Используя метод .HasKey (), свойство может быть явно сконфигурировано как первичный ключ объекта.

using System.Data.Entity;    
// ..

public class PersonContext : DbContext
{
    // ..

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        // ..

        modelBuilder.Entity<Person>().HasKey(p => p.PersonKey);
    }
}

Композитный первичный ключ

Используя метод .HasKey (), набор свойств может быть явно сконфигурирован как составной первичный ключ объекта.

using System.Data.Entity;    
// ..

public class PersonContext : DbContext
{
    // ..

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        // ..

        modelBuilder.Entity<Person>().HasKey(p => new { p.FirstName, p.LastName });
    }
}

Максимальная длина

Используя метод .HasMaxLength (), максимальное количество символов может быть настроено для свойства.

using System.Data.Entity;    
// ..

public class PersonContext : DbContext
{
    // ..

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        // ..

        modelBuilder.Entity<Person>()
                    .Property(t => t.Name)
                    .HasMaxLength(100);
    }
}

Полученный столбец с указанной длиной столбца:

введите описание изображения здесь

Обязательные свойства (NOT NULL)

Используя метод .IsRequired (), свойства могут быть указаны как обязательные, что означает, что столбец будет иметь ограничение NOT NULL.

using System.Data.Entity;    
// ..

public class PersonContext : DbContext
{
    // ..

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        // ..

        modelBuilder.Entity<Person>()
                    .Property(t => t.Name)
                    .IsRequired();
    }
}

Полученный столбец с ограничением NOT NULL:

введите описание изображения здесь

Идентификация внешнего ключа

Когда свойство навигации существует на модели, Entity Framework автоматически создаст столбец внешнего ключа. Если требуется конкретное имя внешнего ключа, но не содержится в качестве свойства в модели, оно может быть установлено явно с использованием Fluent API. Используя метод Map при установлении отношений с внешним ключом, любое уникальное имя может использоваться для внешних ключей.

public class Company
{
    public int Id { get; set; }
}

public class Employee
{
    property int Id { get; set; }
    property Company Employer { get; set; }
}

public class EmployeeContext : DbContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Employee>()
                    .HasRequired(x => x.Employer)
                    .WithRequiredDependent()
                    .Map(m => m.MapKey("EmployerId"));
    }
}

После определения отношения метод Map позволяет явно указать имя внешнего ключа, выполнив MapKey . В этом примере, что привело бы к имени столбца Employer_Id, теперь является EmployerId.



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow