1

仕事が遅い時間に、C# から F# にコーディングした小さな DB アクセス フレームワークを変換したいと考えていました。このフレームワークは、ダイナミクスと ExpandoObjects を広範囲に使用します。特に、頭を悩ませている次のビットがあります。

public static List<dynamic> ToDynamic(this IDataReader reader)
{
    dynamic result = new List<dynamic>();

    while (reader.Read())
    {
        var item = new ExpandoObject();
        var dc = item as IDictionary<String, object>;
        for (int i = 0; i < reader.FieldCount; i++)
        {
            dc.Add(reader.GetName(i), DBNull.Value.Equals(reader[i]) ? null : reader[i]);
        }

        result.Add(item);
    }

    return result;
}

これをどのように F# に変換しますか? これが私が思いつくことができるすべてです:

let (~~) (x:obj) = 
    match x with
    | :? 't as t -> t 
    | _ -> null

let rec mapper (reader : SqlDataReader) : list<'Value> =
    match reader.Read() with
    | false -> []
    | true ->
        let dc = new ExpandoObject()
        let dictionary = ~~dc : Dictionary<string, obj>
        [for i in [0 .. reader.FieldCount - 1] do
            dictionary.Add(reader.GetName(i), reader.GetValue(i))] @ mapper reader

もちろん、ディクショナリはサイクルで null になります。C#の演算子~~を置き換えることになっていたが、as物事はそれほど単純ではないと思う。金曜日のことかもしれませんが、本当に先が見えません。

4

1 に答える 1

2

動的には言語サポートがないため、これは F# に少し関係があります。( のドキュメントを読むことをお勧めしDynamicAttributeます。)翻訳は次のとおりです。

open System.Collections.Generic
open System.Data
open System.Dynamic
open System.Runtime.CompilerServices

[<CompiledName("ToDynamic")>]
let toDynamic (reader: IDataReader) : [<return: Dynamic([|false;true|])>] ResizeArray<obj> = 
  let results = ResizeArray<obj>()
  let rec loop() =
    if reader.Read() then
      let obj = ExpandoObject() :> IDictionary<_,_>
      for i = 0 to reader.FieldCount - 1 do
        obj.Add(reader.GetName(i), if reader.IsDBNull(i) then null else reader.[i])
      results.Add(obj)
      loop()
    else results
  loop()

の値に動的にアクセスするだけの場合IDataReader、F# でのより洗練されたソリューションは、動的演算子をオーバーロードすることです。

let (?) (reader: IDataReader) (name: string) = 
  match reader.[name] with
  | :? DBNull -> Unchecked.defaultof<_>
  | value -> unbox value

//Usage: reader?Id
于 2013-10-25T14:42:54.087 に答える