トレーニングコース。 ASP.NET MVCアプリケーションの複雑なデータモデルの作成、パート1

これは、Entity FrameworkおよびASP.NET MVC 3開発記事シリーズの拡張であり、最初の章は次のリンクにあります。

前のレッスンでは、3つのエンティティで構成される単純なデータモデルを操作する方法を学びました。 このレッスンでは、いくつかのエンティティとそれらの間の関係を追加し、注釈を使用してモデルクラスを管理する方法を学習します。



結果は次のようになります。



image



属性を使用してデータベースのフォーマット、検証、マッピングを制御する



このレッスンでは、モデルクラスに追加してデータベースのフォーマット、検証、マッピングを制御できる属性の例を紹介します。 次に、作成済みのクラスに属性を追加し、モデル内の残りのエンティティタイプの新しいクラスを作成することにより、本格的な学校データモデルを作成します。



DisplayFormat属性



学生の入学日については、すべてのページに日付と時刻が表示されるようになりましたが、日付のみが必要です。 注釈を使用すると、すべてに適用される設定を1か所で指定できます。 これを行うには、StudentクラスのEnrollmentDateプロパティに属性を追加します。



Models \ Studentで csは、System.ComponentModel.DataAnnotationsおよびEnrollmentDateプロパティのDisplayFormat属性を使用して追加します。



using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; namespace ContosoUniversity.Models { public class Student { public int StudentID { get; set; } public string LastName { get; set; } public string FirstMidName { get; set; } [DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)] public DateTime EnrollmentDate { get; set; } public virtual ICollection<Enrollment> Enrollments { get; set; } } }
      
      





フォーマット文字列は、このプロパティの日付の短い形式のみが表示されることを示します。 ApplyFormatInEditMode設定は、この書式設定が編集用のテキスト文字列に表示される値にも適用されることを指定します。 (たとえば、一部のフィールドに表示する必要はありません。たとえば、通貨に関連付けられた値、通貨記号が含まれます)



[バージョン情報]ページと[学生]ページに日付が表示されなくなったことを確認します。



image



MaxLength属性



たとえば、ユーザーが入力した値を50文字に制限する必要がある場合、属性は検証ルールを定義できます。 この機能を利用するには、LastNameプロパティとFirstMidNameプロパティにRange属性を追加します。



 using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; namespace ContosoUniversity.Models { public class Student { public int StudentID { get; set; } [MaxLength(50)] public string LastName { get; set; } [MaxLength(50, ErrorMessage = "First name cannot be longer than 50 characters.")] public string FirstMidName { get; set; } [DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)] public DateTime EnrollmentDate { get; set; } public virtual ICollection<Enrollment> Enrollments { get; set; } } }
      
      





50文字を超える姓を入力しようとすると、標準のエラーメッセージが表示されます。この場合、名前については独自のエラーメッセージが表示されます。



[作成]ページを開き、50文字を超える2つの名前を入力して、[作成]をクリックして検証が機能することを確認します。



image



入力要素の最大値を指定することは、良い習慣の1つです。 それ以外の場合、Code Firstアプローチを使用すると、データベースの作成時に、対応する列の名前に許容される最大長が設定されます。



列属性



属性は、クラスのデータベースへのマッピングを制御できます。 このフィールドにはミドルネームを含めることもできるため、名前フィールドにFirstMidNameという名前を使用したとします。 ただし、ユーザーはクエリでこの名前を使用するため、データベース内の対応する列をFirstNameと呼びます。 これにはColumn属性を使用できます。



Column属性は、データベースの作成時に、FirstMidNameプロパティにマップするStudentテーブルの列がFirstNameと呼ばれることを示します。



この属性をFirstMidNameプロパティに追加します。



 [Column("FirstName")] public string FirstMidName { get; set; }
      
      





何も変更されていない学生インデックスページを開きます(サイトを開始してホームページを見るだけでなく、学生インデックスページに移動してデータベースへのアクセスを開始する必要があり、データベースの削除と再作成もトリガーされます)。 ただし、 サーバー エクスプローラーデータベースを開くと、Studentテーブルの列の名前がFirstNameであることがわかります。



image



[ プロパティ]ウィンドウで、MaxLength属性を使用しているため、長さが50文字に制限されていることがわかります。



image



インストラクターエンティティの作成



image



モデル \ インストラクターを作成します 次のコードを含むcs



 using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; namespace ContosoUniversity.Models { public class Instructor { public Int32 InstructorID { get; set; } [Required(ErrorMessage = "Last name is required.")] [Display(Name="Last Name")] [MaxLength(50)] public string LastName { get; set; } [Required(ErrorMessage = "First name is required.")] [Column("FirstName")] [Display(Name = "First Name")] [MaxLength(50)] public string FirstMidName { get; set; } [DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)] [Required(ErrorMessage = "Hire date is required.")] [Display(Name = "Hire Date")] public DateTime? HireDate { get; set; } public string FullName { get { return LastName + ", " + FirstMidName; } } public virtual ICollection<Course> Courses { get; set; } public virtual OfficeAssignment OfficeAssignment { get; set; } } }
      
      





一部のプロパティはStudentエンティティのプロパティに似ていることに注意してください。 継承の実装では、継承を使用して冗長性の問題を解決します。



必須および表示属性


LastNameプロパティの属性は、この値が入力に必要であることを示します。テキストフィールドの見出しは(「LastName」プロパティの名前ではなく)「Last Name」に等しく、入力値の長さは50文字以下でなければなりません。



 [Required(ErrorMessage = "Last name is required.")] [Display(Name="Last Name")] [MaxLength(50)] public string LastName { get; set; }
      
      





計算されたFullNameプロパティ


FullNameは、他の2つのプロパティを接続して計算された値を含む計算プロパティです。 したがって、アクセサーのみがありますが、対応する列はデータベースに作成されません。



 public string FullName { get { return LastName + ", " + FirstMidName; } }
      
      





ナビゲーションプロパティコースとOfficeAssignment


コースおよびOfficeAssignmentプロパティ-ナビゲーションプロパティ。 前述のように、通常、遅延読み込みを使用するために仮想修飾子でタグ付けされます。 また、このプロパティに複数のエンティティを含めることができる場合、そのタイプはIcollectionである必要があります。



教師は複数のコースを教えることができるため、Courses変数はCourseエンティティのコレクションとして定義されます。 一方、教師はオフィスを1つしか持つことができないため、OfficeAsignmentはOfficeAssignmentタイプの唯一のエンティティとして定義されます(教師がオフィスを持たない場合はnullになります)。



 public virtual ICollection<Course> Courses { get; set; } public virtual OfficeAssignment OfficeAssignment { get; set; }
      
      





OfficeAssignmentエンティティの作成



image



Models \ OfficeAssignmentを作成します 次の内容のcs



 using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; namespace ContosoUniversity.Models { public class OfficeAssignment { [Key] public int InstructorID { get; set; } [MaxLength(50)] [Display(Name = "Office Location")] public string Location { get; set; } public virtual Instructor Instructor { get; set; } } }
      
      





キー属性


InstructorのエンティティとOfficeAssignmentの間に1対0または1の関係があります。 指定されたオフィスは指定された教師と組み合わせてのみ存在するため、そのプライマリキーはインストラクターエンティティに対する外部キーでもあります。 ただし、Entity Frameworkは、InstructorIDを主キーとして自動的に認識できません。これは、このプロパティの名前が主キーの命名規則に準拠しておらず、IDとclassnameIDが等しくないためです。 したがって、キー属性は、この属性が主キーであることを示します。



 [Key] public int InstructorID { get; set; }
      
      





Key属性は、主キーが既にあるが、 クラス名 IDまたはIDとは異なるプロパティに名前を付けたい場合にも使用できます。



インストラクターナビゲーションプロパティ


エンティティインストラクターは、null許容のOfficeAssignmentナビゲーションプロパティです(教師にはオフィスがない場合があります)。エンティティOfficeAssignmentには、null不可のインストラクターナビゲーションプロパティがあります(教師なしではオフィスは存在できません)。 インストラクターにOfficeAsignmentエンティティが関連付けられている場合、両方のナビゲーションプロパティに相互リンクがあります。



継続するには...



謝辞



Alexander Belotserkovsky( ahriman )の翻訳にご協力いただきありがとうございます。



All Articles