fsharp里通过Type Provide访问数据库或许是一个更好的办法,丰富的上下文提示,直观的接口。但只支持的数据库比较单一,默认只有一个SqlServer,又让Type Provide显得有些单薄。
Enterprise Library是微软提供的一套辅助功能应用库,这套库的目的主要还是提供最好的轮子。通过Ioc的方式能够极大的提升开发的效率,降低错误发生可能。另一方面我觉得Ioc是今后的以发展方向,在划分系统功能的过程中先绕开这些辅助功能模块,着眼主要逻辑,即简化了系统的设计,也让系统之后的维护性大大的增强了。
Enterprise Library提供了多个子模块。先从数据库说起。
使用组建的第一步通过NuGet得到相关的组件。数据库用到的不多,一个Common,一个Data,在Enterprise Library下很容易就能找到。安装好之后便使用FSI(fsharp的交互环境)尝试关键对象的生成,使用。选中代码块使用【Alt+Enter】进行命令执行
1.引入Dll,Xpath需要替换
在这里有一些说明,我理解配置文件中生成的对象和通过代码生成的对象都是一样的。这里使用配置文件来获取配置
4.操作Database的代码。
a.生成数据库
Enterprise Library是微软提供的一套辅助功能应用库,这套库的目的主要还是提供最好的轮子。通过Ioc的方式能够极大的提升开发的效率,降低错误发生可能。另一方面我觉得Ioc是今后的以发展方向,在划分系统功能的过程中先绕开这些辅助功能模块,着眼主要逻辑,即简化了系统的设计,也让系统之后的维护性大大的增强了。
Enterprise Library提供了多个子模块。先从数据库说起。
使用组建的第一步通过NuGet得到相关的组件。数据库用到的不多,一个Common,一个Data,在Enterprise Library下很容易就能找到。安装好之后便使用FSI(fsharp的交互环境)尝试关键对象的生成,使用。选中代码块使用【Alt+Enter】进行命令执行
1.引入Dll,Xpath需要替换
#if INTERACTIVE
#r "[Xpath]/packages/EnterpriseLibrary.Data.6.0.1304.0/lib/NET45/Microsoft.Practices.EnterpriseLibrary.Data.dll"
#r "[Xpath]/packages/EnterpriseLibrary.Common.6.0.1304.0/lib/NET45/Microsoft.Practices.EnterpriseLibrary.Common.dll"
#r "System"
#r "System.Data"
#r "System.Configuration"
#endif
2.引入命名空间,定义辅助函数
open System
open System.Data
open System.Data.Common
open System.Data.SqlClient
open Microsoft.Practices.EnterpriseLibrary.Data
open Microsoft.Practices.EnterpriseLibrary.Common.Configuration
open Microsoft.Practices.EnterpriseLibrary.Data.Sql
open Microsoft.Practices.EnterpriseLibrary.Data.Configuration
open System.Threading
open System.Threading.Tasks
open System.Configuration
let DisplayRowValue (reader:IDataReader) =
while reader.Read() do
for i = 0 to reader.FieldCount-1 do
Console.WriteLine("{0}={1}", reader.GetName(i), reader.[i].ToString())
Console.WriteLine()
3.定义配置文件
在这里有一些说明,我理解配置文件中生成的对象和通过代码生成的对象都是一样的。这里使用配置文件来获取配置
<?xml version="1.0"?>
<configuration>
<configSections>
<section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true" />
<section name="connectionStrings" type="System.Configuration.ConnectionStringsSection, System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" requirePermission="true" />
</configSections>
<dataConfiguration defaultDatabase="ExampleDatabase" />
<connectionStrings>
<add name="ExampleDatabase" connectionString="Data Source=(localdb)\v11.0;AttachDbFilename=E:\WorkHell\fsharp-practise\EnterpriseLibraryPractise\DataAccessExamples.mdf;Integrated Security=True"
providerName="System.Data.SqlClient" />
<add name="AsyncExampleDatabase" connectionString="Data Source=(localdb)\v11.0;Asynchronous Processing=true;AttachDbFilename=|DataDirectory|\DataAccessExamples.mdf;Integrated Security=True"
providerName="System.Data.SqlClient" />
<add name="DataAccessExample.Properties.Settings.DataAccessExamplesConnectionString"
connectionString="Data Source=(localdb)\v11.0;AttachDbFilename=|DataDirectory|\DataAccessExamples.mdf;Integrated Security=True"
providerName="System.Data.SqlClient" />
</connectionStrings>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
</startup>
</configuration>
我尽量让代码在交互和编译环境下都能运行,不过这里configSections的第二个对象connectionStrings在编译环境中是不需要的,系统会显示重复声明的提示
4.操作Database的代码。
a.生成数据库
#if COMPILED
let factory = new DatabaseProviderFactory()
#else
let path = __SOURCE_DIRECTORY__ + "\FsiApp.config"
let fileMap = ConfigurationFileMap(path)
let config = ConfigurationManager.OpenMappedMachineConfiguration(fileMap)
let factory = new DatabaseProviderFactory(fun s -> config.GetSection(s))
#endif
let defaultDB = factory.CreateDefault()
b.最简单的操作,通过sql语句与通过存储过程操作数据库
let reader = defaultDB.ExecuteReader(CommandType.Text, "select top 1 * from orderlist")
DisplayRowValue reader
let reader = defaultDB.ExecuteReader("ListOrdersByState", [|box "Colorado"|])//box var type object
DisplayRowValue reader
这里还有地方要留意, 代码中的reader是一个系统资源,一般在程序中我们用use关键字进行声明使用如同csharp中的using一样。不过在交互环境中由于变量总是在作用域范围内,所以最好还是使用fsharp的using关键字
using(defaultDB.ExecuteReader("GetProductList", [|box "%bike%"|]))(fun reader ->
DisplayRowValue reader)
后续介绍sql参数,异步模型。