サーチ…


備考

HOW Entity FrameworkがPOCOクラスをデータベーステーブル、列などにマップすることを指定する一般的な方法は2つあります。 データ注釈Fluent API

データ注釈は読みやすく、理解しやすいものですが、エンティティの「削除時にカスケード」動作を指定するなどの機能はありません。一方、Fluent APIはもう少し複雑ですが、はるかに高度な機能を提供します。

モデルのマッピング

EntityFramewok Fluent APIは、 コードファーストドメインモデルを基になるデータベースにマッピングする、強力かつエレガントな方法です。これは既存のデータベースコードファーストで使用することもできますFluent APIを使用する場合は、 OnModelCreatingメソッドでモデルを直接マップするか、 EntityTypeConfigurationから継承したマッパークラスを作成して、 OnModelCreatingメソッドのmodelBuilderにそのモデルを追加することができます。 第二の選択肢は私が好むもので、その例を示すつもりです。

ステップ1:モデルを作成します。

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

ステップ2:マッパークラスを作成する

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 - プロパティがデータベースレベルで計算されるかどうかを指定します。数値のPKはDatabaseGeneratedOption.Identityです。デフォルトでは、そうしたくない場合はDatabaseGeneratedOption.Noneを指定する必要があります。
  • HasMaxLength - 文字列の長さを制限します。
  • IsRequired - プロパティを再クエリとしてマークします。
  • HasPrecision - 小数点以下の桁数の精度を指定できます。
  • Ignore - プロパティを完全に無視し、データベースにマップしません。 FullNameは無視されました。なぜなら、この列をテーブルに入れたくないからです。
  • ToTable - モデルのテーブル名とスキーマ名(オプション)を指定します。
  • HasColumnName - プロパティを列名に関連付けます。プロパティー名と列名が同一である場合、これは必要ありません。

ステップ3:マッピングクラスを構成に追加します。

マッパークラスを使用するようにEntityFrameworkに指示する必要があります。これを行うには、 OnModelCreatingメソッドのmodelBuilder.Configurationsに追加する必要あります。

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を実行して外部キー名を明示的に設定MapKeyます。この例では、Employer_Idの列名になったのは今ではEmployerIdです。



Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow