在Code First方法中,还可以通过Fluent API的方式来处理实体与数据表之间的映射关系。
要使用Fluent API必须在构造自定义的DbContext时,重写OnModelCreating方法,在此方法体内调用Fluent API。
如下面代码所示:
public
class
BlogDbContext : DbContext
{
public BlogDbContext()
: base ( " name=BlogDB2005 " )
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// do something
base .OnModelCreating(modelBuilder);
}
}
{
public BlogDbContext()
: base ( " name=BlogDB2005 " )
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// do something
base .OnModelCreating(modelBuilder);
}
}
下面来看一些简单的例子
主键
modelBuilder.Entity
<
BlogUser
>
().HasKey(user
=>
user.UserId);
联合主键
//
联合主键
modelBuilder.Entity < BlogUser > ().HasKey(user => new { user.UserId, user.BlogName });
modelBuilder.Entity < BlogUser > ().HasKey(user => new { user.UserId, user.BlogName });
字段非空
//
要求属性必填
modelBuilder.Entity < BlogUser > ().Property(user => user.BlogName).IsRequired();
modelBuilder.Entity < BlogUser > ().Property(user => user.BlogName).IsRequired();
设定字段最大长度
modelBuilder.Entity
<
BlogUser
>
().Property(user
=>
user.BlogName).HasMaxLength(
20
);
设置复杂属性,相当数据特性中的ComplexType
modelBuilder.ComplexType
<
Address
>
();
属性字段不映射到数据表字段,相当于数据特性中的NotMapped
modelBuilder.Entity
<
BlogUser
>
().Ignore(user
=>
user.MyProperty);
设置字段是否自动增长
//
设置自动增长,如不需要自动增长,则设为 DatabaseGeneratedOption.None
modelBuilder.Entity < BlogUser > ().Property(user => user.UserId)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
modelBuilder.Entity < BlogUser > ().Property(user => user.UserId)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
设置外键
///
产生一对多的关系
modelBuilder.Entity < Post > ()
.HasRequired(p => p.BlogUser)
.WithMany(user => user.Posts)
.HasForeignKey(p => p.UserId);
/// 与上面等效
// modelBuilder.Entity<BlogUser>()
// .HasMany(user => user.Posts)
// .WithRequired(p => p.BlogUser)
// .HasForeignKey(p => p.UserId);
modelBuilder.Entity < Post > ()
.HasRequired(p => p.BlogUser)
.WithMany(user => user.Posts)
.HasForeignKey(p => p.UserId);
/// 与上面等效
// modelBuilder.Entity<BlogUser>()
// .HasMany(user => user.Posts)
// .WithRequired(p => p.BlogUser)
// .HasForeignKey(p => p.UserId);
设定实体映射到数据库中的表名
modelBuilder.Entity
<
BlogUser
>
().ToTable(
"
MyUser
"
);
设置实体属性映射到数据库中的列名
modelBuilder.Entity
<
BlogUser
>
()
.Property(user => user.Description)
.HasColumnName( " userDescription " )
.HasColumnType( " ntext " );
.Property(user => user.Description)
.HasColumnName( " userDescription " )
.HasColumnType( " ntext " );
下面给出完整代码,方便测试:
class
FluentAPISample
{
static void Main( string [] args)
{
using (var db = new BlogDbContext())
{
db.Database.Create();
}
}
}
public class BlogDbContext : DbContext
{
public BlogDbContext()
: base ( " name=BlogDB2005 " )
{
Database.SetInitializer < BlogDbContext > (
new DropCreateDatabaseIfModelChanges < BlogDbContext > ()
);
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity < BlogUser > ().HasKey(user => user.UserId);
// 联合主键
// modelBuilder.Entity<BlogUser>().HasKey(user => new { user.UserId, user.BlogName });
// 设置自动增长,如不需要自动增长,则设为 DatabaseGeneratedOption.None
modelBuilder.Entity < BlogUser > ().Property(user => user.UserId)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
// 要求属性必填
modelBuilder.Entity < BlogUser > ().Property(user => user.BlogName).IsRequired();
modelBuilder.Entity < BlogUser > ().Property(user => user.BlogName).HasMaxLength( 20 );
modelBuilder.Entity < BlogUser > ().Ignore(user => user.MyProperty);
modelBuilder.ComplexType < Address > ();
/// 产生一对多的关系
modelBuilder.Entity < Post > ()
.HasRequired(p => p.BlogUser)
.WithMany(user => user.Posts)
.HasForeignKey(p => p.UserId);
/// 与上面等效
// modelBuilder.Entity<BlogUser>()
// .HasMany(user => user.Posts)
// .WithRequired(p => p.BlogUser)
// .HasForeignKey(p => p.UserId);
modelBuilder.Entity < BlogUser > ().ToTable( " MyUser " );
modelBuilder.Entity < BlogUser > ()
.Property(user => user.Description)
.HasColumnName( " userDescription " )
.HasColumnType( " ntext " );
base .OnModelCreating(modelBuilder);
}
}
public partial class BlogUser
{
public int UserId { get ; set ; }
public string BlogName { get ; set ; }
public int MyProperty { get ; set ; }
public Address Address { get ; set ; }
public string Description { get ; set ; }
public virtual ICollection < Post > Posts { get ; set ; }
}
public partial class Post
{
public int PostId { get ; set ; }
public string PostTitle { get ; set ; }
public int UserId { get ; set ; }
public BlogUser BlogUser { get ; set ; }
}
public partial class Address
{
public string Province { get ; set ; }
public string City { get ; set ; }
}
{
static void Main( string [] args)
{
using (var db = new BlogDbContext())
{
db.Database.Create();
}
}
}
public class BlogDbContext : DbContext
{
public BlogDbContext()
: base ( " name=BlogDB2005 " )
{
Database.SetInitializer < BlogDbContext > (
new DropCreateDatabaseIfModelChanges < BlogDbContext > ()
);
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity < BlogUser > ().HasKey(user => user.UserId);
// 联合主键
// modelBuilder.Entity<BlogUser>().HasKey(user => new { user.UserId, user.BlogName });
// 设置自动增长,如不需要自动增长,则设为 DatabaseGeneratedOption.None
modelBuilder.Entity < BlogUser > ().Property(user => user.UserId)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
// 要求属性必填
modelBuilder.Entity < BlogUser > ().Property(user => user.BlogName).IsRequired();
modelBuilder.Entity < BlogUser > ().Property(user => user.BlogName).HasMaxLength( 20 );
modelBuilder.Entity < BlogUser > ().Ignore(user => user.MyProperty);
modelBuilder.ComplexType < Address > ();
/// 产生一对多的关系
modelBuilder.Entity < Post > ()
.HasRequired(p => p.BlogUser)
.WithMany(user => user.Posts)
.HasForeignKey(p => p.UserId);
/// 与上面等效
// modelBuilder.Entity<BlogUser>()
// .HasMany(user => user.Posts)
// .WithRequired(p => p.BlogUser)
// .HasForeignKey(p => p.UserId);
modelBuilder.Entity < BlogUser > ().ToTable( " MyUser " );
modelBuilder.Entity < BlogUser > ()
.Property(user => user.Description)
.HasColumnName( " userDescription " )
.HasColumnType( " ntext " );
base .OnModelCreating(modelBuilder);
}
}
public partial class BlogUser
{
public int UserId { get ; set ; }
public string BlogName { get ; set ; }
public int MyProperty { get ; set ; }
public Address Address { get ; set ; }
public string Description { get ; set ; }
public virtual ICollection < Post > Posts { get ; set ; }
}
public partial class Post
{
public int PostId { get ; set ; }
public string PostTitle { get ; set ; }
public int UserId { get ; set ; }
public BlogUser BlogUser { get ; set ; }
}
public partial class Address
{
public string Province { get ; set ; }
public string City { get ; set ; }
}
运行结果如下图示: