EntityFramework實體映射到數據庫
在Entity Framework Code First與數據表之間的映射方式實現:
1、Fluent API映射
通過重寫DbContext
上的OnModelCreating
方法來訪問Code First Fluent API
例如:
public class BlogDbContext: DbContext { public BlogDbContext() : base("BlogDbContext") { } public DbSet<BlogUser> BlogUser{ get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity<BlogUser>().HasKey(k => k.BlogUserId) //主鍵 .Property(q => q.BlogName).IsRequired();//不能為空 } }
demo中的property方法用於為每個屬於實體或復雜類型的屬性配置特性。Property 方法用於獲取給定屬性的配置對象。配置對象上的選項特定於要配置的類型;例如,IsRequired表示不可為空。
- ToTable - TableAttribute:配置此實體類型映射到的表名
- HasColumnName - ColumnAttribute:配置用於存儲屬性的數據庫列的名稱
- HasForeignKey - ForeignKeyAttribute:將關系配置為使用在對象模型中的外鍵屬性。如果未在對象模型中公開外鍵屬性,則使用Map方法
- Ignore - NotMappedAttribute:從模型中排隊某個屬性,使該屬性不會映射到數據庫
- HasRequired:通過此實體類型配置必需關系。除非指定此關系,否則實體類型的實例將無法保存到數據庫。數據庫中的外鍵不可為null。
- HasOptional:從此實體類型配置可選關系。實體類型的實例將能保存到數據庫,而無需指定此關系。數據庫中的外鍵可為null。
- HasMany:從此實體類型配置一對多關系。
- WithOptional:將關系配置為required:optional。(required:0…1端的1,表示必需,不可為null;optional:0…1端的0,表示可選,可為null。下同)
- WithOptionalDependent:將關系配置為optional:optional。要配置的實體類型將成為依賴對象,且包含主體的外鍵。作為關系目標的實體類型將成為關系中的主體。
- WithOptionalPrincipal:將關系配置為optional:optional。要配置的實體類型將成為關系中的主體。作為關系目標的實體類型將成為依賴對象,且包含主體的外鍵。
- WithRequired:將關系的指定端配置為必需的,且在關系的另一端有導航屬性。
- WithRequiredDependent:將關系配置為required:required。要配置的實體類型將成為依賴對象,且包含主體的外鍵。作為關系目標的實體類型將成為關系中的主體。
- WithRequiredPrincipal:將關系配置為required:required。要配置的實體類型將成為關系中的實體。作為關系目標的實體類型將成為依賴對象,且包含主體的外鍵。
- WillCascadeOnDelete:配置是否對關系啟用級聯刪除。
- Map:將關系配置為使用未在對象模型中公開的外鍵屬性。可通過指定配置操作來自定義列和表。如果指定了空的配置操作,則約定將生成列名。如果在對象模型中公開了外鍵屬性,則使用 HasForeignKey 方法。並非所有關系都支持在對象模型中公開外鍵屬性。
- MapKey:配置外鍵的列名。
- ToTable:配置外鍵列所在表的名稱和架構
參考資料:https://msdn.microsoft.com/zh-cn/library/gg696117
如果這時候需要修改BlogUser這個實體,比如添加一個字段的時候直接運行就會報錯,此時需要進行數據庫更新遷移
建一個遷移類
using BlogDemo.Repositories; using System; using System.Collections.Generic; using System.Data.Entity.Migrations; using System.Linq; using System.Web; namespace BlogDemo.Migrations { public class Configuration:DbMigrationsConfiguration<BlogDbContext> { /// <summary> /// 初始化一個<see cref="MigrationsConfiguration"/>類型的新實例 /// </summary> public Configuration() { //啟用自動遷移 AutomaticMigrationsEnabled = true; //獲取或設置一個值表示如果在自動數據丟失是可以接受的 [慎重設置] AutomaticMigrationDataLossAllowed = true; } } }
同時也需要在Global.asax里面添加應用程序初始化的時候把數據庫更新為最新的辦法
protected void Application_Start() { //數據庫初始化為最新的版本 Database.SetInitializer(new MigrateDatabaseToLatestVersion<BlogDbContext,Configuration>()); AreaRegistration.RegisterAllAreas(); // 默認情況下對 Entity Framework 使用 LocalDB //Database.DefaultConnectionFactory = new SqlConnectionFactory(@"Data Source=(localdb)\v11.0; Integrated Security=True; MultipleActiveResultSets=True"); RegisterGlobalFilters(GlobalFilters.Filters); RegisterRoutes(RouteTable.Routes); }
這個時候基本的操作可以實現,但是在實際的項目中數據表肯定不止一兩張,幾十張甚至上百張,如果按照這樣的配置方法,需要配置映射關系的時候在 BlogDbContext的OnModelCreating進行配置,到后面在OnModelCreating方法中會添加很多關系
所以此時的解決方法就是新加一個映射類,在這個類中引用EntityTypeConfiguration,其實在BlogDbContext的OnModelCreating中有一句代碼是modelBuilder.Entity<BlogUser>().HasKey(m => m.BlogUserId); haskey轉到定義可看到
所以在這里引用EntityTypeConfiguration是為了可以在構造方法中寫配置,如下:
public class BlogUserConfiguration : EntityTypeConfiguration<BlogUser>,IEntityMapper { public BlogUserConfiguration() { //設置主鍵 HasKey(m => m.BlogUserId); } }
這樣我們就可以不用在OnModelCreating中配置,可以把之前的代碼刪掉,用modelBuilder.Configurations.Add(new BlogUserConfiguration());
這樣我們就用了這個通用的接口替換了OnModelCreating方法
在BlogDbContext中的 public DbSet<BlogUser> BlogUser{ get; set; } 可以注釋掉,然后直接用DbContext.Set<TEntity>()方法來實現指定實體的屬性
如下:
var dbContext = new BlogDbContext(); IQueryable<BlogUser> blogUser= dbContext.Set<BlogUser>(); blogUser.ToList();
2、Data Annotation驗證
所引用程序集:System.ComponentModel.DataAnnotations
Data Annotation主要是在實體類的屬性上加入需要驗證的條件
例如:
StringLength表示字符長度限制50位,如果超過此長度則提示"輸入過長,不能超過50位";
[Required(ErrorMessage = "Name is required")] public string Name { get; set; } [Required(ErrorMessage = "Email is required")] [RegularExpression(@"^\s*([A-Za-z0-9_-]+(\.\w+)*@([\w-]+\.)+\w{2,3})\s*$", ErrorMessage = "Email is invalid")] public string Email { get; set; }
Required()表示這個屬性是必填的,ErrorMessage的值是必填項沒有填時,顯示的錯誤提示信息
RegularExpression()是正則表達式驗證,只有符合正則表達式的字符串才能通過驗證
Fluent API和Data Annotation配置數據庫映射參考博文
http://www.cnblogs.com/oppoic/p/ef_default_mapping_and_data_annotations_fluent_api.html