使用NoRM从F#访问MongoDB

时间:2010-11-27 21:08:12

标签: f# mongodb norm

从F#测试NoRM https://github.com/atheken/NoRM并尝试找到一种很好的方法来使用它。这是基本的C#:

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());
}

这可以正常工作,但这是我从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

3 个答案:

答案 0 :(得分:1)

您是否尝试过记录类型?

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

我不知道它是否有效,但是当你只需要一个基本上是“一组字段”的类时,记录通常都很好。

答案 1 :(得分: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#编译器添加无参数构造函数。)

答案 2 :(得分:0)

这是一个非常轻松的方法来定义一个接近你的C#定义的类:它有一个默认的构造函数,但使用公共字段而不是getter和setter,这可能是一个问题(我不知道)。

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