从 F# 调用 EF Core HasIndex

Calling EF Core HasIndex from F#

我正在尝试重写一个 C# EF Core 示例(类似于 the one in the docs) into F#. I have a problem with HasIndex。在 C# 中,调用是 HasIndex(b => b.Isbn),以在 Isbn 列上创建索引:

public class SampleContext : DbContext
{
    public DbSet<Book> Books { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Book>().HasIndex(b => b.Isbn);
    }
}

在 F# 中做同样的事情,HasIndex(fun b -> b.Isbn),不编译:

type public SampleContext() =
    inherit DbContext()

    [<DefaultValue>]
    val mutable books: DbSet<Book>

    member x.Books
        with get() = x.books
        and set v = x.books <- v

    override __.OnModelCreating(modelBuilder) =
        modelBuilder.Entity<Book>().HasIndex(fun b -> b.Isbn) // doesn't compile
        |> ignore

我需要使用一些引号魔法来完成这项工作吗?

(您当然可以使用字符串 HasIndex("Isbn"),但我不希望在编译时检查 window。)

根据https://social.msdn.microsoft.com/Forums/vstudio/en-US/a0757965-4d13-4f88-910f-9ab5fd96277d/how-to-convert-c-linq-expression-in-f?forum=fsharpgeneral中接受的答案:

"F# 3.0 or later should apply a type-directed conversion when you pass a lambda where an Expression is expected."

似乎 F# 3.0 及更高版本将转换 lambda,只要您用括号将其括起来并将 return 值转换为 C# 方法期望的特定类型(在本例中 "Sytem.Object")

所以:

modelBuilder.Entity<Book>().HasIndex( (fun b -> b.Isbn :> System.Object ) )

在 .net core 2.0 中编译成功