要更改EF中的默認配置有兩個方法,一個是用Data Annotations(在命名空間System.ComponentModel.DataAnnotations;),直接作用於類的屬性上面;還有一個就是Fluent API,通過新增相應的配置類來覆蓋默認配置。現在我們用這兩個來對比了解EF中的約定配置。
主鍵:KEY
Data Annotations:通過Key關鍵字來標識一個主鍵
[Key] public int DestinationId { get; set; }
Fluent API:
public class BreakAwayContext : DbContext { public DbSet<Destination> Destinations { get; set; } public DbSet<Lodging> Lodgings { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { //Fluent API modelBuilder.Entity<Destination>().HasKey(d => d.DestinationId); base.OnModelCreating(modelBuilder); } }
外鍵
Data Annotations:
public int DestinationId { get; set; } [ForeignKey("DestinationId")] public Destination Destination { get; set; }
注意,指定列名存在,如上面的DestinationId,則類中必須存在名稱為DestinationId的屬性。
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來標識,還可以設置是否可允許空字符串,顯示錯誤消息等。
[Required] public string Country { get; set; } [Required(ErrorMessage="請輸入描述")] public string Description { get; set; }
Fluent API:
modelBuilder.Entity<Destination>().Property(p => p.Country).IsRequired();
數據類型
Data Annotations:TypeName
//將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
[Table("MyLodging")] public class Lodging { public int LodgingId { get; set; } public string Name { get; set; } public string Owner { get; set; } public decimal Price { get; set; } public bool IsResort { get; set; } public Destination Destination { get; set; } }
Fluent API:
modelBuilder.Entity<Lodging>().ToTable("MyLodging");
列名
Data Annotations:Column
[Column("MyName")] public string Name { get; set; }
Fluent API:
modelBuilder.Entity<Lodging>().Property(p => p.Name).HasColumnName("MyName");
自增長
如果主鍵是int類型,EF為默認設置為增長。但如果是GUID類型,則要顯示的設置自增長。
Data Annotations:DatabaseGenerated
public class Person { [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] public Guid SocialId { get; set; } public string FirstName { get; set; } public string LastName { get; set; } }
看看創建數據的腳本,會加一句
ALTER TABLE [dbo].[People] ADD DEFAULT (newid()) FOR [SocialId]
Fluent API:
modelBuilder.Entity<Person>().Property(p => p.SocialId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
忽略列映射
類中有些屬性,特別是一些通過計算或合並列得出的結果,我們並不需要其記錄到數據庫中,就可以通過配置不讓它生成在數據庫中。
Data Annotations:NotMapped
[NotMapped] public string Name { get { return FirstName + " " + LastName; } }
Fluent API:NotMapped
modelBuilder.Entity<Person>().Ignore(p => p.Name);
忽略表映射
對於不需要映射到數據庫中的表,我們也可以取消其映射。
Data Annotations:
[NotMapped] public class Person { [Key] public Guid SocialId { get; set; } public string FirstName { get; set; } public string LastName { get; set; } }
Fluent API:
modelBuilder.Ignore<Person>();
時間戳
時間戳只對數據類型為byte[]的屬性有效,並且一個類中只能有一個設置為時間戳的屬性。
Data Annotations:Timestamp
[Timestamp] public Byte[] TimeStamp { get; set; }
Fluent API:
modelBuilder.Entity<Lodging>().Property(p => p.TimeStamp).IsRowVersion();
復雜類型
Data Annotations:ComplexType
[ComplexType] public class Address { public string Country { get; set; } public string City { get; set; } }
Fluent API:
modelBuilder.ComplexType<Address>();
關於什么是復雜類型,可以參見:http://www.cnblogs.com/Gyoung/archive/2013/01/17/2864747.html