2010-11-27 4 views
0

F #에서 NoRM https://github.com/atheken/NoRM을 테스트하고이를 사용하는 좋은 방법을 찾으려고합니다. NoRM을 사용하여 F에서 MongoDB에 액세스 #

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 

클래스를 만들거나 제네릭 메서드에 전달할 입력하는 쉬운 방법이 있나요 :

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 번호에서 액세스하는 방법입니다 : 여기에 기본 C 번호는 ?

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# 정의에 가까운 클래스를 정의하는 아주 간단한 방법입니다. 기본 생성자가 있지만 문제가 될 수도있는 getters 및 setters 대신 public 필드를 사용합니다 (잘 모르겠습니다).

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

:) 나는 그것을 두려워했다. 이러한 프레임 워크가 getter에게 공개 필드를 똑같이 다루지 않을 때 나는 항상 짜증이났다. 두 가지를 모두 지원하기 위해 그렇게 많은 노력을해서는 안되며, 그렇게하지 않는 철학적 인 이유가 없다. NoRM에 기능 요청을 할 수 있습니다. 이는 그들이 수용력이 있다고 주장하기 때문이며 경쟁사가이를 지원할 수 있음을 지적 할 수 있습니다. –

+0

난 대답을주는거야 왜냐하면 거기에 파티가 없었더라도, 내가 물어보고 있었어 – yanta

1

당신이 레코드 종류를 시도 : 여기

그것이라고 어떻게?

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

작동 여부는 잘 모르지만 기본적으로 '필드 세트'인 클래스 만 필요할 때가 있습니다.

+0

먼저 이것을 시도했지만 NoRM 드라이버가 '이 객체에 대해 정의 된 매개 변수없는 생성자가 없습니다.'예외를 throw합니다. – yanta

+0

mongodb-csharp는 동일한 문제가 있으며 Activator.CreateInstance (ClassType, true)를 사용합니다. 레코드를 사용할 때 위의 예외가 throw됩니다 – 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)는 여전히 '이 개체에 대해 정의 된 매개 변수없는 생성자가 없습니다.'예외를 throw합니다. 작은 테스트 응용 프로그램 및 심지어 t.GetConstructor (new Type [] {}); null를 돌려줍니다. 그러나 제품을 클래스 (레코드가 아님)로 변경하면 제대로 작동합니다. 리플렉터는 주요 차이점은 레코드가 봉인 된 것이라고 제안합니다. 그렇다면 왜 작동하지 않습니까? – yanta