2016-09-15 6 views
3

...私は、内側がFの#で参加したいC#で次の種類を考える Entity FrameworkのとF#で入会C#で簡単な作業では、F#でそう簡単ではいないようであるように思わ何

public partial class Foo 
{ 
    public long FooID { get; set; } 
    public long BarID { get; set; } 
    public bool SomeColumn1 { get; set; } 
} 

public partial class Bar 
{ 
    public long ID { get; set; } 
    public string SomeColumn1 { get; set; } 
    public bool SomeColumn2 { get; set; } 
} 

だから、これを行うことで、私の試みは、次のとおりです。

let dbContext = DatabaseManager.Instance.ProduceContext() 

let barIdForeignKey(f: Foo) = 
    f.BarID 

let barIdPrimaryKey(b: Bar) = 
    b.ID 

let joinResult(f: Foo, b: Bar) = 
    (f, b) 

let joinedElements = 
    dbContext.foos.Join(dbContext.bars, barIdForeignKey, barIdPrimaryKey, joinResult) 

しかし、コンパイラは次のように文句を言う:

可能な過負荷:(拡張子)

System.Collections.Generic.IEnumerable.Join<'TOuter, 'TInner, 'TKey, 'TResult>(
    inner:   System.Collections.Generic.IEnumerable<'TInner>, 
    outerKeySelector: System.Func<'TOuter, 'TKey>, 
    innerKeySelector: System.Func<'TInner, 'TKey>, 
    resultSelector: System.Func<'TOuter, 'TInner, 'TResult>) 
    : System.Collections.Generic.IEnumerable<'TResult> 

タイプの制約の不一致。タイプ'd * 'e -> foo * barはタイプSystem.Func<'a, 'b, 'c>

タイプ'd * 'e -> foo * barと互換性がないタイプSystem.Func<'a, 'b, 'c>

ないこれを読んでどのようにしてくださいとの互換性はありません。私は最後にタプルを返すことができないのでしょうか? C#で私はnew { Foo = foo, Bar = bar }のような匿名型が必要ですが、F#でそれを行う方法はわかりません。最後にまで単純化することができる

let dbContext = DatabaseManager.Instance.ProduceContext() 

let barIdForeignKey(f: Foo) = 
    f.BarID 

let barIdPrimaryKey(b: Bar) = 
    b.ID 

let joinResult(f: Foo) (b: Bar) = 
    (f, b) 

let joinedElements = 
    dbContext.foos.Join(dbContext.bars, barIdForeignKey, barIdPrimaryKey, joinResult) 

:最後FUNCためcurrified引数を使用して

+4

はなぜ[クエリ式]を使用しない(https://docs.microsoft.com/en-us/dotnet/ articles/fsharp/language-reference/query-expressions)?いずれにしても、 'let joinResult(f:Foo、b:Bar)='を 'let joinResult(f:Foo)(b:Bar)='に変更してみてください。 – ildjarn

+1

ORMを使用する場合、結合は*非常に*強い臭いです。それらは、マッピングが間違っていて、いくつかの重要な関係が欠落していることを意味します。 'Foo'が' Bar'プロパティを持っていれば、あなたは参加する必要はありません。 EFは、関連するエンティティをロードするための適切なSQLを生成します。関連するエンティティを熱心に読み込むか遅れて読み込むかを制御することができます。 –

+2

F#関数は、メソッド呼出し時に自動的にF#関数を.NETデリゲート型(例: 'Func <_,_,_>')に変換するが、タプル入力ではなくカレートを使用する必要がある(例えば 'let joinResult(f:Foo)(b:Bar)= ...)。 – kvb

答えて

2

ソリューション(感謝@ildjarn)

let joinedElements = 
    dbContext.foos.Join (dbContext.bars, 
         (fun f -> f.barID), 
         (fun b -> b.ID), 
         (fun f b -> (f,b)) 
         ) 

@PanagiotisKanavosも私に合流についてのヒントを与えましたORMがコードスモールであることを利用して、Fooクラスに実際にBarというプロパティがあることがわかりました(このBarプロパティがEntityFrameworによってフードの下に設定されているのでkとにかく)。これ、query expressionsを使用するための@ ildjarnのオリジナルの提案と合わせ、最良の答えに私を導いた:

let dbContext = DatabaseManager.Instance.ProduceContext() 

let joinedElements = 
    query { 
     for foo in dbContext.foos do 
      select (foo.Bar, foo.SomeColumn1) 
    } 
関連する問題