「深刻な」CRUDアプリケーションでは、データベースが最重要になることは広く受け入れられています。 それは最初に設計されており、ストアドプロシージャ(ストアドプロシージャ)で大きくなりすぎており、最も気にする必要があります。 しかし、これが唯一の方法ではありません! Entity Frameworkには、コードファーストアプローチがあり、主なものはベースではなくコードです。 利点:
- コードは生成されません
- ここでも、ベースは単なるリポジトリです。 震える必要はありません。簡単に問題なく落下します。
- 開発環境の最も簡単なインストール。 コードをアップロードして実行しました-バックアップで大騒ぎしません。
いくつかの欠点がありますが、それらはEntity Frameworkに関連している可能性が高く、Code Firstアプローチ自体には関連していません。 それらについては少し後で。
以下に、コードファーストアプローチを使用した開発がいかに簡単かを例で示します。
例
簡単なモデルを見てください:
フロントエンドはASP.NET MVCになるため、適切なプロジェクトを作成します。 [ 認証なし]を選択します-このプロジェクトではログインできず、すべてのコンテンツをすべてのユーザーが利用できます。
さらに2つのプロジェクトを作成しました-ビジネスオブジェクトとDAL用ですが、必要に応じて、Webプロジェクトに適切なフォルダーを作成するだけです。 NuGetを介して適切なプロジェクトにEntity Frameworkをインストールすることを忘れないでください。
エンティティを表示するクラスを作成します。
public abstract class BaseEntity { [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public Guid ID { get; set; } }
public class Course : BaseEntity { public string Title { get; set; } public int Credits { get; set; } public ICollection<Enrollment> Enrollments { get; set; } }
public class Student : BaseEntity { public string Name { get; set; } public int Age { get; set; } public DateTime EnrollmentDate { get; set; } public virtual ICollection<Enrollment> Enrollments { get; set; } }
public class Enrollment : BaseEntity { public Guid CourseID { get; set; } public Guid StudentID { get; set; } public Grade CourseGrade { get; set; } public virtual Student Student { get; set; } public virtual Course Course { get; set; } }
ご覧のとおり、すべての繰り返しプロパティを抽象クラスに削除して、抽象クラスから継承できます。 この場合、各テーブルには、データベースへの書き込み時に生成されるGuidタイプの主キー列があります。
Gradeは単なる列挙子であり、特別なものはありません。
public enum Grade { A,B,C,D,E,F }
コンテキストクラスを作成します。
public class UniversityContext : DbContext { public UniversityContext() : base("UniversityContext") { } public DbSet<Course> Courses { get; set; } public DbSet<Enrollment> Enrollments { get; set; } public DbSet<Student> Students { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder.Entity<Student>() .HasMany(s => s.Enrollments) .WithRequired(e => e.Student) .HasForeignKey(e => e.StudentID); modelBuilder.Entity<Course>() .HasMany(c => c.Enrollments) .WithRequired(e => e.Course) .HasForeignKey(e => e.CourseID); } }
関係は、Fluent APIを介して定義され、最後から読み込まれます。たとえば、Student-Enrollmentは、1(Student):many(Enrollment)として扱われます。
Fluent APIと注釈の両方を使用してモデルを構成できることに注意してください。 一部の設定では、注釈は存在しませんが、 自分で作成できます 。 私はまだFluent APIを好みます。
最後に、データベースにデータを入力します。
public class UniversityInitializer : System.Data.Entity.DropCreateDatabaseIfModelChanges<UniversityContext> { protected override void Seed(UniversityContext context) { var studentList = new List<Student>() { new Student(){ Age = 20, EnrollmentDate = DateTime.Now, Name = "Basil Ivanov" }, new Student(){ Age = 18, EnrollmentDate = DateTime.Now, Name = "Boris Ivan" }, new Student(){ Age = 27, EnrollmentDate = DateTime.Now, Name = "Masha Ivanova" }, new Student(){ Age = 23, EnrollmentDate = DateTime.Now, Name = "Vytautas" }, new Student(){ Age = 21, EnrollmentDate = DateTime.Now, Name = "Ivan" } }; studentList.ForEach(s => context.Students.Add(s)); context.SaveChanges(); var courseList = new List<Course>() { new Course(){ Credits = 10, Title = "Maths"}, new Course(){ Credits = 20, Title = "Advanced maths"}, new Course(){ Credits = 10, Title = "Physics"} }; courseList.ForEach(c => context.Courses.Add(c)); context.SaveChanges(); var enrollments = new List<Enrollment>() { new Enrollment(){ Course = context.Courses.FirstOrDefault(c => c.Title=="Maths"), Student = context.Students.FirstOrDefault()}, new Enrollment(){ Course = context.Courses.FirstOrDefault(c => c.Title=="Physics"), Student = context.Students.FirstOrDefault()}, new Enrollment(){ Course = context.Courses.FirstOrDefault(c => c.Title=="Physics"), Student = context.Students.FirstOrDefault(s => s.Name == "Boris Ivan")} }; enrollments.ForEach(e => context.Enrollments.Add(e)); context.SaveChanges(); } }
注 : DropCreateDatabaseIfModelChangesという名前が示すように、対応するモデルクラスに変更が加えられると、ベースはドロップします。 つまり、データはkaputです。
データが入力されないように移行を実装する方法は、この記事の範囲外です。
最後に行うことは、web.configに情報を追加することです。 Visual Studioに付属するLocalDbを使用します。これは、このプロジェクトの目的には十分です。 次のコードは構成要素に移動します 。
<connectionStrings> <add name="UniversityContext" connectionString="Data Source=(LocalDb)\v11.0;;AttachDbFilename=|DataDirectory|\UnivCRUD.mdf;Initial Catalog=UniversityCRUD;Integrated Security=SSPI;" providerName="System.Data.SqlClient"/> </connectionStrings>
そして、次のマークアップがentityFramework要素にあります。
<contexts> <context type="UniversityCRUD.DA.UniversityContext, UniversityCRUD.DA"> <databaseInitializer type="UniversityCRUD.DA.UniversityInitializer, UniversityCRUD.DA" /> </context> </contexts>
コンテキスト要素のtype属性では、このクラスが存在するコンテキストクラスとアセンブリの名前がコンマで示されます。 同じことが、 databaseInitializer要素の初期化子についても言えます 。
これですべてです。プロジェクトを立ち上げる準備ができました。
Visual Studio 2013では、[ 追加]-> [新しい足場アイテム ]ダイアログを使用して、選択したモデルにコントローラーとビューをすばやく生成できます。
こちらからサンプルをダウンロードできます。
欠点
まず、既存のデータベースに同様のアプローチを適用するのは困難です。 したがって、実際にはこれはゼロから開発するためのものです。
多くの場合、Entity Frameworkが時流をかけます。これは、多くの場合プログラマーの決定を下します。たとえば、Idというプロパティがデフォルトで主キーテーブルに変換される、いわゆる規則があります。 私はこのアプローチが好きではありません。
トピックの続き
Entity FrameworkのCode Firstアプローチによる開発は、膨大なトピックです。 移行の問題、マルチスレッドの問題(同時実行性)などには対処しませんでした。 コミュニティに興味があれば、今後の記事でこのトピックを続けることができます。
材料:
1. MVC 5を使用してEntity Framework 6 Code Firstを開始する
2. Code-Firstでのデータベースの初期化
3. Lerman J.、Miller R.-Entity Frameworkのプログラミング。 コードファースト(2011)