演练:根据 EDMX 架构文件生成 F# 类型 (F#)

此针对 F# 3.0 的演练演示如何创建由实体数据模型 (EDM)(在 .edmx 文件中指定的架构)表示的数据的类型。 此演练还演示如何使用 EdmxFile 类型提供程序。 开始之前,请考虑 SqlEntityConnection 类型提供程序是否为更适当的类型提供程序选项。 SqlEntityConnection 类型提供程序最适合以下方案:在项目的开发阶段,你具有可连接到的实时数据库,并且你不介意在编译时指定连接字符串。 但是,此类型提供程序还会受到限制,它公开的数据库功能没有 EdmxFile 类型提供程序公开的数据库功能那样多。 此外,如果你不具有使用实体数据模型的数据库项目的实时数据库连接,则可使用 .edmx 文件针对数据库进行编码。 在你使用 EdmxFile 类型提供程序时,F# 编译器将运行 EdmGen.exe 以生成其提供的类型。

此演练演示了下列任务,你必须按以下顺序执行这些任务才能成功完成演练:

  • 创建 EDMX 文件

  • 创建项目

  • 查找或创建实体数据模型连接字符串

  • 配置类型提供程序

  • 查询数据

  • 调用存储过程

创建 EDMX 文件

如果你已具有 EDMX 文件,则可跳过此步骤。

创建 EDMX 文件

  • 如果你尚没有 EDMX 文件,则可按照本演练末尾的步骤配置实体数据模型中的说明执行操作。

创建项目

在此步骤中,创建一个项目并添加对该项目的适当引用以使用 EDMX 类型提供程序。

创建并设置 F# 项目

  1. 关闭前一个项目并创建另一个项目,然后将其命名为 SchoolEDM。

  2. 在**“解决方案资源管理器”中,打开“引用”的快捷菜单,然后选择“添加引用”**。

  3. 在**“程序集”区域中,选择“框架”**节点。

  4. 在可用程序集的列表中,选择 System.Data.EntitySystem.Data.Linq 程序集,然后选择**“添加”**按钮以将对这些程序集的引用添加到你的项目。

  5. 在**“程序集”区域中,选择“扩展”**节点。

  6. 在可用扩展的列表中,添加对 FSharp.Data.TypeProviders 程序集的引用。

  7. 添加以下代码以打开相应的命名空间。

    open System.Data.Linq
    open System.Data.Entity
    open Microsoft.FSharp.Data.TypeProviders
    

查找或创建实体数据模型的连接字符串

实体数据模型的连接字符串(EDMX 连接字符串)不仅包括数据库提供程序的连接字符串,还包括附加信息。 例如,简单 SQL Server 数据库的 EDMX 连接字符串类似于以下代码。

let edmConnectionString = "metadata=res://*/;provider=System.Data.SqlClient;Provider Connection String='Server=SERVER\Instance;Initial Catalog=DatabaseName;Integrated Security=SSPI;'"

有关 EDMX 连接字符串的更多信息,请参见连接字符串

查找或创建实体数据模型的连接字符串

  • EDMX 连接字符串难以手动生成,因此你可以通过编程方式生成该字符串来节省时间。 如果你知道 EDMX 连接字符串,则可绕过此步骤,只需在下一步中使用该字符串即可。 如果你不知道该字符串,请使用以下代码从你提供的数据库连接字符串生成 EDMX 连接字符串。

    open System
    open System.Data
    open System.Data.SqlClient
    open System.Data.EntityClient
    open System.Data.Metadata.Edm
    
    let getEDMConnectionString(dbConnectionString) =
        let dbConnection = new SqlConnection(connectionString)
        let resourceArray = [| "res://*/" |]
        let assemblyList = [| System.Reflection.Assembly.GetCallingAssembly() |]
        let metaData = MetadataWorkspace(resourceArray, assemblyList)
        new EntityConnection(metaData, dbConnection)
    

配置类型提供程序

在此步骤中,你使用 EDMX 连接字符串创建并配置类型提供程序,并为 .edmx 文件中定义的架构生成类型。

配置类型提供程序和生成类型

  1. 将本演练的步骤 1 中生成的 .edmx 文件复制到你的项目文件夹。

  2. 打开你的 F# 项目中项目节点的快捷菜单,选择**“添加现有项”**,然后选择 .edmx 文件以将其添加到你的项目中。

  3. 输入以下代码以激活 .edmx 文件的类型提供程序。 将 Server\Instance 替换为正在运行 SQL Server 的服务器的名称和你的实例的名称,并使用本演练的步骤 1 中创建的 .edmx 文件的名称。

    type edmx = EdmxFile<"Model1.edmx", ResolutionFolder = @"<folder that contains your .edmx file>>
    
    let edmConnectionString =
        getEDMConnectionString("Data Source=SERVER\instance;Initial Catalog=School;Integrated Security=true;")
    let context = new edmx.SchoolModel.SchoolEntities(edmConnectionString)
    

查询数据

在此步骤中,你使用 F# 查询表达式查询数据库。

查询数据

  • 输入以下代码以查询实体数据模型中的数据。

    query { for course in context.Courses do
            select course }
    |> Seq.iter (fun course -> printfn "%s" course.Title)
    
    query { for person in context.Person do
            select person }
    |> Seq.iter (fun person -> printfn "%s %s" person.FirstName person.LastName)
    
    // Add a where clause to filter results
    query { for course in context.Courses do
            where (course.DepartmentID = 1)
            select course)
    |> Seq.iter (fun course -> printfn "%s" course.Title)
    
    // Join two tables
    query { for course in context.Courses do
            join (for dept in context.Departments -> course.DepartmentID = dept.DepartmentID)
            select (course, dept.Name) }
    |> Seq.iter (fun (course, deptName) -> printfn "%s %s" course.Title deptName)
    

调用存储过程

你可使用 EDMX 类型提供程序来调用存储过程。 在下一个过程中,School 数据库包含存储过程 UpdatePerson,该过程将在为列提供了新值的情况下更新记录。 你可以使用此存储过程,因为该过程已作为 DataContext 类型的方法公开。

调用存储过程

  • 添加以下代码以更新记录。

    // Call a stored procedure.
    let nullable value = new System.Nullable<_>(value)
    
    // Assume now that you must correct someone's hire date.
    // Throw an exception if more than one matching person is found.
    let changeHireDate(lastName, firstName, hireDate) =
    
        query { for person in context.People do
                where (person.LastName = lastName &&
                       person.FirstName = firstName)
                exactlyOne }
        |> (fun person ->
                context.UpdatePerson(nullable person.PersonID, person.LastName,
                    person.FirstName, nullable hireDate, person.EnrollmentDate))
    
    changeHireDate("Abercrombie", "Kim", DateTime.Parse("1/12/1998"))
    |> printfn "Result: %d"
    

    如果操作成功,则结果为 1。 请注意,在查询表达式中使用 exactlyOne 可确保仅返回一个结果;否则,将引发异常。 此外,若要更轻松地使用可以为 null 的值,你可使用此代码中定义的简单 nullable 函数来利用一般值创建可为 null 的值。

配置实体数据模型

应仅在你需要了解如何从数据库生成完整的实体数据模型且你不具有要测试的数据库时,完成该过程。

配置实体数据模型

  1. 在菜单栏上,依次选择**“SQL”“Transact-SQL 编辑器”“新建查询”**以创建数据库。 如果系统提示你,请指定你的数据库服务器和实例。

  2. 复制并粘贴创建 Student 数据库的数据库脚本的内容,如数据开发人员中心的实体框架文档中所述。

  3. 通过选择带三角形符号的工具栏按钮或选择 Ctrl+Q 键来运行 SQL 脚本。

  4. 在**“服务器资源管理器”中,打开“数据连接”的快捷菜单,选择“添加连接”**,然后输入数据库服务器的名称、实例的名称和 School 数据库的名称。

  5. 创建 C# 或 Visual Basic 控制台应用程序项目,打开其快捷菜单,选择**“添加新项”,然后选择“ADO.NET 实体数据模型”**。

    实体数据模型向导随即打开。 通过使用此向导,你可以选择所需的创建实体数据模型的方式。

  6. 在**“选择模型内容”下,选中“从数据库生成”**复选框。

  7. 在下一页上,选择新创建的 School 数据库作为数据连接。

    此连接应与 <servername>.<instancename>.School.dbo 类似。

  8. 将实体连接字符串复制到剪贴板,因为该字符串稍后可能会很重要。

  9. 确保选中用于将实体连接字符串保存到 App.Config 文件的复选框,并记下文本框中的字符串值,这将帮助你稍后在需要时找到该连接字符串。

  10. 在下一页上,选择**“表”“存储过程和函数”**。

    通过选择这些顶级节点,可以选择所有表、存储过程和函数。 如果需要,也可以单独选择这些项。

  11. 确保选中其他设置所对应的复选框。

    第一个**“确定所生成对象名称的单复数形式”**复选框指示是否将单数形式更改为复数形式以匹配表示数据库表的命名对象中的约定。 **“在模型中包括外键列”**复选框确定是否包含用于联接到对象类型中为数据库架构生成的其他字段的字段。 第三个复选框指示是否在模型中包括存储过程和函数。

  12. 选择**“完成”**按钮以生成包含基于 School 数据库的实体数据模型的 .edmx 文件。

    文件 Model1.edmx 将添加到你的项目中,并且将显示数据库关系图。

  13. 在菜单栏上,依次选择**“视图”“其他窗口”“实体数据模型浏览器”以查看模型的所有详细信息,或选择“实体数据模型映射详细信息”**以打开一个窗口,该窗口演示生成的对象模型如何映射到数据库表和列上。

后续步骤

通过查看查询表达式 (F#) 中列出的可用查询运算符来浏览其他查询。

请参见

任务

演练:使用类型提供程序和实体访问 SQL 数据库 (F#)

参考

EdmxFile 类型提供程序 (F#)

EDM 生成器 (EdmGen.exe)

其他资源

类型提供程序

Entity Framework

.edmx File Overview (Entity Framework)