65.9K
CodeProject 正在变化。 阅读更多。
Home

EF Feature CTP5 - 代码优先流畅 API

starIconstarIconstarIconstarIconstarIcon

5.00/5 (3投票s)

2010 年 12 月 8 日

CPOL

2分钟阅读

viewsIcon

27822

EF Feature CTP5 - 代码优先流畅 API

代码优先 的主要特性之一是流式 API。这个 API 可以帮助你配置模型,从而更好地塑造它(以及数据库)。 在这篇文章中,我将展示一个简单的例子,说明如何使用流式 API。 请注意,我提供的细节可能会在未来发生变化,因为它只是一个 CTP,而不是正式发布版。

示例模型

在示例中,我将使用以下模型

public class SchoolEntities : DbContext
{
  #region Properties
 
  public DbSet<Course> Courses { get; set; }
  public DbSet<Department> Departments { get; set; }
 
  #endregion
 
  #region Methods
 
  protected override void OnModelCreating(
    System.Data.Entity.ModelConfiguration.ModelBuilder modelBuilder)
  {
    base.OnModelCreating(modelBuilder);
 
    // put here the fluent code
  }
 
  #endregion
}
 
public partial class Course
{
  #region Properties
 
  public int CourseID { get; set; }
  public string Title { get; set; }
  public string Days { get; set; }
  public DateTime Time { get; set; }
  public string Location { get; set; }
  public int Credits { get; set; }
  public int DepartmentID { get; set; }
 
  public virtual Department Department { get; set; }
 
  #endregion
}
 
public class Department
{
  #region Properties
 
  public int DepartmentID { get; set; }
  public string Name { get; set; }
  public decimal Budget { get; set; }
  public DateTime StartDate { get; set; }
  public int Administrator { get; set; }
 
  public virtual ICollection<Course> Courses { get; set; }
 
  #endregion
}

流式 API 示例

在你创建模型之后,有很多方法可以使用流式 API 来配置模型。 主要的配置位置是在 OnModelCreating 方法中,你需要在 DbContext 中重写该方法。 该方法会获得一个 ModelBuilder 实例,该实例可以用来配置模型。 以下示例展示了如何使用 API 编写一些配置

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
  base.OnModelCreating(modelBuilder);
 
  modelBuilder.Entity<Department>().
    Property(d => d.Name).
    IsRequired().
    HasMaxLength(50);
 
  modelBuilder.Entity<Department>().
    Property(d => d.DepartmentID).
    HasDatabaseGenerationOption(DatabaseGenerationOption.None);
 
  modelBuilder.Entity<Department>().
    HasMany(d => d.Courses).
    WithRequired(c => c.Department).
    HasForeignKey(c => c.DepartmentID).
    WillCascadeOnDelete();
 
  modelBuilder.Entity<Department>().
    Ignore(d => d.Administrator);
 
  modelBuilder.Entity<Course>().
    Property(c => c.Title).
    IsRequired().
    HasColumnName("Name");      
}

配置了什么?

让我们解释一下上述代码中看到的内容。 当我想配置一个实体时,我使用带有实体作为泛型参数的 Entity 方法。 然后我就可以使用流式 API 并开始配置我的模型了。 在第一行中,我将部门的 Name 属性配置为必需,并且长度不超过 50 个字符。 在第二行中,我将 DepartmentID 配置为非数据库生成(因为默认情况下所有 ID 都会由数据库生成)。 第三行在部门和它的课程集合之间创建了一对多的关系。 你首先使用 HasMany 来指示多的那一侧,然后使用 WithRequired 来指示一对多的关系中的“一”的一侧。 HasForeignKey 指示多的一侧的外键。 最后一个方法,WillCascadeOnDelete,将在实体图中添加级联删除。 第四行将强制模型忽略部门的 administrator 属性,因此它不会在数据库中生成。 第五行指示 Title 属性是必需的,并且在数据库中列名将是 Name 而不是 Title。 这里有一个创建数据并将其插入数据库的简单示例

class Program
{
  static void Main(string[] args)
  {
    using (SchoolEntities context = new SchoolEntities())
    {
      var department = new Department
      {
        DepartmentID = 1,
        Administrator = 2,
        Budget = 100000,
        Name = "Data Access",
        StartDate = DateTime.Now
      };
      var course = new Course
      {
        Credits = 2,
        Days = "MF",
        Location = "Class 1",
        Time = DateTime.Now,
        Title = "Entity Framework",
        Department = department,
      };
      context.Departments.Add(department);
      context.SaveChanges();
    }
  }
}

运行这个示例将生成一个名为 ClassLibrary1.SchoolEntities 的新数据库,其中包含在 OnModelCreating 方法中编写的所有配置。 如果你想更改生成的数据库名称(默认情况下从 namespace 和上下文名称获取),你需要创建一个构造函数到 DbContext 中,并调用接受 string 作为参数的基础构造函数

public SchoolEntities() :
      base("MySchool")
    {
 
    }

生成的数据库如下所示

Database

摘要

让我们总结一下,代码优先 具有一个非常有趣的功能,即流式 API流式 API 用于模型配置,易于理解和使用。 在这篇文章中,我展示并解释了 API 的一小部分。

© . All rights reserved.