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>();