在C#中看似容易的任务,在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)
但是编译器会报错,类似于:
Possible overload: (extension)
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>
Type constraint mismatch. The type
'd * 'e -> foo * bar
is not compatible with typeSystem.Func<'a, 'b, 'c>
The type
'd * 'e -> foo * bar
is not compatible with the typeSystem.Func<'a, 'b, 'c>
不确定如何阅读这个。也许是因为我不能在结尾处返回元组?在C#中,我需要一个匿名类型,比如new { Foo = foo, Bar = bar }
,但我不确定如何在F#中实现。
let joinResult(f: Foo, b: Bar) =
更改为let joinResult (f: Foo) (b: Bar) =
。 (意思是建议在代码中使用查询表达式,并将一个带有两个参数的函数更改为两个带有单个参数的函数) - ildjarnFoo
有一个Bar
属性,您就不需要连接。EF会生成适当的SQL来加载相关实体。您可以控制相关实体是急切地加载还是懒惰地加载。 - Panagiotis KanavosFunc<_,_,_>
),但您需要使用柯里化而不是元组输入(例如let joinResult (f:Foo) (b:Bar) = ...
)。 - kvb