entity-framework - 加入 Entity Framework 和 F#

标签 entity-framework linq f# anonymous-types c#-to-f#

在 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 type System.Func<'a, 'b, 'c>

The type 'd * 'e -> foo * bar is not compatible with the type System.Func<'a, 'b, 'c>

不确定如何阅读此内容。也许是我最后不能返回一个元组?在 C# 中,我需要一个匿名类型,比如 new { Foo = foo, Bar = bar } ,不确定如何在 F# 中执行此操作。

最佳答案

解决方案(感谢@ildjarn)对最后一个函数使用柯里化(Currying)参数:

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)

这最后可以简化为:

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

@PanagiotisKanavos 也给了我关于使用 ORM 的连接是一种代码味道的提示,这让我发现 Foo 中实际上有一个 Bar 属性类(这样我就不需要摆弄 BarID 列,因为这个 Bar 属性无论如何都是由 EntityFramework 在后台填充的)。这与@ildjarn 最初关于使用 query expressions 的建议相结合, 让我找到了最佳答案:

let dbContext = DatabaseManager.Instance.ProduceContext()

let joinedElements =
    query {
        for foo in dbContext.foos do
            select (foo.Bar, foo.SomeColumn1)
    }

关于entity-framework - 加入 Entity Framework 和 F#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39511324/

相关文章:

c# - Entity Framework - 不支持列 'ColumnName' 的类型。类型是 'Object'

Linq:计数大于值的情况

C# - 遍历谓词的模式

scripting - 通过 F# 解释脚本

http - 在 Suave 应用程序中上传文件

c# - 使用linq删除gridview中的行

c# - edmx 计算列

c# - Entity Framework TypeUsage 对象

c# - 我可以内联指定我的显式类型比较器吗?

macos - Fsharp.Data,HtmlDocument 没有扩展后代