EF-CodeFirst-1 玩起來
EF-CodeFirst-1 玩起來
註本文是學習旺傑兄的CodeFirst系列所寫
CodeFirst
CodeFirst是一種全新的玩法,代碼先行使得我們更了解實體之間的關系。而且更加符合了DDD領域驅動設計的思想 。所以CodeFirst已經成為了一種趨勢。
簡單玩法
打開Visual Studio新建一個類庫,然後新建項目 ADO.NET實體數據模型-->空的CodeFirst模型
這裏定義了兩個實體 User與UserRole,字段UserRoles、User代表著一個User可以擁有多個UserRole。而一個UserRole對應著一個User。這裏有一個外鍵關系
然後需要在我們的剛才新建的項目類中加上這樣兩行代碼,熟悉的朋友看到這裏會很明顯的感覺到這就是DbFirst生成的Context
然後別忘了在config中加上連接字符串,加上後就可以嗨皮去了!!
最後在MVC項目中(其它的也可以) 進行添加一個數據試試看。運行過後去數據庫裏就可以看到這個庫以及我們添加的記錄了
註:如果報錯 正在創建此模型,此時不可使用上下文…. ,請在程序包管理器控制器使用命令 Updata-Base 。下面會有一系列操作按照提示來就可以了
實體的一些配置
我們在數據庫新建表的時候,往往會給字段設置主建、非空、數據類型大小等。在這裏也可以做到。上面我們使用了Data Annotations。
Data Annotations 翻譯後就是數據註解。可以使用Attribute在實體類上進行註解
比如
[key] 、[Required]、[Table]等
還用一種就是使用Fluent API (流利的API),在DbContext中定義的數據庫配置映射的一種方式。在集成自DbContext的類中重寫OnModelCreatring方法
這樣配置有些麻煩,因為每個實體類都要在這邊寫上一行,慢慢的越來越大不說,還不便於維護,一堆代碼這麽多我想修改其中某個實體類的話還需要去翻找上一陣子。這就比較尷尬了。
好的方法是為每個實體類單獨的做配置然後在這邊進行統一管理即可
- 新建繼承自EntityTypeConfiguration<>的類,建議以實體類名+Map結尾
- 在類的構造函數中進行編寫配置
- 添加到上下文的OnModelCreating方法中
一些配置的玩法,即用即看
//【主鍵】
//Data Annotations:
[Key]
public int DestinationId { get; set; }
//Fluent API:
public class BreakAwayContext : DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Destination>().HasKey(d => d.DestinationId);
}
}
//【外鍵】
//Data Annotations:
public int DestinationId { get; set; }
[ForeignKey("DestinationId")]
public Destination Destination { get; set; }
//Fluent API:
modelBuilder.Entity<Lodging>().HasRequired(p => p.Destination).WithMany(p=>p.Lodgings).HasForeignKey(p => p.DestinationId);
//【長度】
//Data Annotations:通過StringLength(長度),MinLength(最小長度),MaxLength(最大長度)來設置數據庫中字段的長度
[MinLength(10),MaxLength(30)]
public string Name { get; set; }
[StringLength(30)]
public string Country { get; set; }
//Fluent API:沒有設置最小長度這個方法
modelBuilder.Entity<Destination>().Property(p => p.Name).HasMaxLength(30);
modelBuilder.Entity<Destination>().Property(p => p.Country).HasMaxLength(30);
//【非空】
//Data Annotations:
[Required(ErrorMessage="請輸入描述")]
public string Description { get; set; }
//Fluent API:
modelBuilder.Entity<Destination>().Property(p => p.Country).IsRequired();
//【數據類型】
Data Annotations:
將string映射成ntext,默認為nvarchar(max)
[Column(TypeName = "ntext")]
public string Owner { get; set; }
//Fluent API:
modelBuilder.Entity<Lodging>().Property(p => p.Owner).HasColumnType("ntext");
//【表名】
//Data Annotations:
[Table("MyLodging")]
public class Lodging
{
}
//Fluent API
modelBuilder.Entity<Lodging>().ToTable("MyLodging");
//【列名】
//Data Annotations:
[Column("MyName")]
public string Name { get; set; }
//Fluent API:
modelBuilder.Entity<Lodging>().Property(p => p.Name).HasColumnName("MyName");
//【自增長】
//Data Annotations
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] Guid類型的主鍵、自增長
public Guid SocialId { get; set; }
//Fluent API:
modelBuilder.Entity<Person>().Property(p => p.SocialId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
//【忽略列映射】
//Data Annotations:
[NotMapped]
public string Name
{
get
{
return FirstName + " " + LastName;
}
}
//Fluent API:
modelBuilder.Entity<Person>().Ignore(p => p.Name);
//【忽略表映射】
//Data Annotations:
[NotMapped]
public class Person
{ }
//Fluent API:
modelBuilder.Ignore<Person>();
//【時間戳】
//Data Annotations:Timestamp
[Timestamp]
public Byte[] TimeStamp { get; set; } 只能是byte類型
//Fluent API:
modelBuilder.Entity<Lodging>().Property(p => p.TimeStamp).IsRowVersion();
//【復雜類型】
//Data Annotations:
[ComplexType]
public class Address
{
public string Country { get; set; }
public string City { get; set; }
}
//Fluent API:
modelBuilder.ComplexType<Address>();
EF-CodeFirst-1 玩起來