2010-11-27 10 views
0

F#のNoRM https://github.com/atheken/NoRMを試してみて、使い方を見つけようとしています。ここでは、基本的なC#がある:NoRMを使用してFからMongoDBにアクセスする#

class products 
{ 
    public ObjectId _id { get; set; } 
    public string name { get; set; } 
} 

using (var c = Mongo.Create("mongodb://127.0.0.1:27017/test")) 
{ 
    var col = c.GetCollection<products>(); 
    var res = col.Find(); 
    Console.WriteLine(res.Count().ToString()); 
} 

これはOK動作しますが、ここで私はF#のからそれをアクセスする方法である:

type products() = 
    inherit System.Object() 

    let mutable id = new ObjectId() 
    let mutable _name = "" 

    member x._id with get() = id and set(v) = id <- v 
    member x.name with get() = _name and set(v) = _name <- v 

ジェネリックメソッドに渡すクラスまたはタイプを作成するための簡単な方法があります?ここで

は、それが呼ばれる方法です。

use db = Mongo.Create("mongodb://127.0.0.1:27017/test") 
let col = db.GetCollection<products>() 
let count = col.Find() |> Seq.length 
printfn "%d" count 
+0

RavenDBはF#でうまく動作しますが、ソースツリーにF#の例がいくつかあります。https://github.com/ravendb/ravendb/tree/master/Samples/Raven.Sample.FSharp/ – Robert

+0

興味深いですが、プロジェクトがオープンソースの場合は無料でRavenを使用してください。商用ソフトウェアを構築するためにRavenを使用する場合は、商用ライセンスを購入する必要があります。 http://www.ravendb.net/licensing – yanta

答えて

0

ここでは、C#定義に近いクラスを定義するための非常に軽い方法です:デフォルトのコンストラクタがありますが、ゲッターやセッターの代わりにパブリックフィールドを使用しています(わかりません)。

type products = 
    val mutable _id: ObjectId 
    val mutable name: string 
    new() = {_id = ObjectId() ; name = ""} 

や、あなたのフィールドのデフォルト値を使用できるかどうか(この場合は、すべてのNULL):

type products() = 
    [<DefaultValue>] val mutable _id: ObjectId 
    [<DefaultValue>] val mutable name: string 
+0

簡潔さが戻ってきました!残念ながらNoRMではプロパティを探しているようですが、_idとnameはフィールドとしてコンパイルされます。これはmongodb-csharpでも動作します。 – yanta

+0

:)私はそれを恐れていた。私はこれらのフレームワークがゲッターと同じように公開フィールドを扱わないときはいつも迷惑です。両方をサポートするために余計な努力をすべきではありませんし、そうでない哲学的理由も見当たりません。おそらく、彼らは受容的であると主張しているので、NoRMに機能要求を出すことができます(そして、競争相手がこれをサポートしていることを指摘することができます)。 –

+0

私はこれを答えとして与えています。なぜなら、アフターパーティーはなくても、 – yanta

1

あなたはレコードタイプを試してみましたか?

type products = { 
    mutable _id : ObjectId 
    mutable name : string 
    } 

それが動作するかどうかは知りませんが、単に「フィールドのセット」を基本的にクラスを必要とするとき、レコードは、多くの場合、良いです。

+0

私はこれを最初に試みましたが、NoRMドライバは例外 'このオブジェクトに対して定義されたパラメータのないコンストラクタはありません。'をスローします。 – yanta

+0

mongodb-csharpにも同じ問題があり、Activator.CreateInstance(ClassType、true)を使用します。レコードを使用すると上記の例外がスローされます – yanta

1

ただ、好奇心のうちは、あなたがにパラメータなしのコンストラクタを追加してみてくださいすることができます記録。これは間違いなくハックです - 実際には、F#コンパイラのバグを利用している - しかし、それは動作可能性があります

type Products = 
    { mutable _id : ObjectId 
    mutable name : string } 
    // Horrible hack: Add member that looks like constructor 
    member x.``.ctor``() =() 

member宣言がコンストラクタで使用される特殊な.NETの名前を持つメンバーを追加しますので、 .NETはコンストラクタだと考えています。私はこれを使用することに非常に注意していますが、メンバーがReflectionを介してコンストラクタとして表示されるため、あなたのシナリオではうまくいくかもしれません。

これは、MongoDBのようなライブラリで動作する簡潔な型宣言を得る唯一の方法であれば、F#チームが将来のバージョンの言語で問題を解決することを望んでいます(例えば、 F#コンパイラにパラメータのないコンストラクタを追加させる)。

+0

おお、それはかなり野生です。私は見回して、レコード型のパラメーターのないコンストラクターを使用することが可能かどうかを尋ねる多くの質問を見て、すべてが不可能だと言っていました... –

+0

しかし、レコード参照型のデフォルトコンストラクタの前に、通常の参照型用に実装されたプロパティ。確かにクラスや構造体を簡潔に定義することができるさまざまな方法がありますが、私はそれだけで十分ではなく、いつも仕事を終わらせるための最も冗長な手段が必要です。これらの範囲内で実装された簡潔な機能を持つ参照および構造体の型を作成する一貫した方法を見たいと思います。 –

+1

これはうまくいきません。リフレクタを見ると、.ctor()メソッドが作成されますが、Activator.CreateInstance(t、false)は引き続き例外 'このオブジェクトに対して定義されたパラメータなしのコンストラクタなし'をスローします。私は小さなテストアプリケーションでもこれを試してみました。さらに、t.GetConstructor(新しいType [] {}); nullを返します。しかし、製品をクラス(レコードではない)に戻すと、正常に動作します。リフレクターは、主な違いはレコードが封印されていることを示唆しています。なぜそれは機能しませんか? – yanta

関連する問題