【问题标题】:Cassandra CQL Mapping in F#F# 中的 Cassandra CQL 映射
【发布时间】:2016-04-03 00:17:28
【问题描述】:

我在尝试将我的类型上的属性映射到 Cassandra 中的映射时遇到问题。

我在 C# 中工作,但我在 F# 中苦苦挣扎

我得到的错误是: Stack Trace: [System.ArgumentOutOfRangeException: Expression x => new Tuple`2(x.Id, ToFSharpFunc(x => x.WithName("player_id"))) 不是属性或场地。参数名称:表达式]

在第 26 行,如果我删除了 "fun(x:ColumnMap)->x.WithName("player_id")" 它会编译但它不会映射到正确的表列。我的模型属性名称是“Id”,但我需要它映射到“player_id”

open Cassandra
open Cassandra.Mapping
open System

type Ranking = 
{ Id : Guid
  Alias : string
  Kills : int
  Deaths : int }

type Player = {Id: Guid; Alias: string; Dob: DateTime; FullName: string}

type CassyMappings() = 
inherit Cassandra.Mapping.Mappings()
do 
    base.For<Player>()
            .TableName("players")
            .PartitionKey("player_id")
            .Column(fun(x:Player)-> x.Id) 
            .Column(fun(x:Player)-> x.Alias)
            .Column(fun(x:Player)-> x.FullName)
            .Column(fun(x:Player)-> x.Dob) |> ignore
    base.For<Ranking>()
        .TableName("rankings")
        .PartitionKey("player_id")
        .Column(fun (x : Ranking) -> x.Id, fun(x:ColumnMap)->x.WithName("player_id")) 
        .Column(fun (x : Ranking) -> x.Alias)
        .Column(fun (x : Ranking) -> x.Kills)
        .Column(fun (x : Ranking) -> x.Deaths) |> ignore

MappingConfiguration.Global.Define<CassyMappings>()

printfn "Works fine!"

https://dotnetfiddle.net/8IiYhg

这里是 C# http://www.datastax.com/dev/blog/csharp-driver-cassandra-new-mapper-linq-improvements的链接

【问题讨论】:

  • 将您的代码放入实际问题中。另外,请解释“在 F# 中挣扎是什么意思”——包括任何错误消息等。
  • 当然,没问题.. 我为它创建了一个 DotNetFiddle here 我的错误是“堆栈跟踪:[System.ArgumentOutOfRangeException: Expression x => new Tuple`2(x.Id, ToFSharpFunc( x => x.WithName("player_id"))) 不是属性或字段。参数名称:表达式]"
  • 在第 26 行,如果我删除了 "fun(x:ColumnMap)->x.WithName("player_id")" 它会编译但它不会映射到正确的表列。我的模型属性名称是“Id”,但我需要它映射到“player_id”
  • 把所有这些包括实际代码,而不是问题中的链接。

标签: f# cassandra


【解决方案1】:

你缺少括号。

第 26 行的表达式被编译为:

.Column(fun (x : Ranking) -> (x.Id, fun(x:ColumnMap)->x.WithName("player_id")) )

也就是说,作为一个表达式,它以Ranking 作为参数并产生一个int 的元组和一个函数作为结果。为了更清楚起见,这里是相同代码的更扩展版本:

.Column(
   fun (x : Ranking) -> 
      let id = x.Id
      let f = fun (x:ColumnMap)->x.WithName("player_id")
      id, f )

这种表达式的结果是 Tuple&lt;_,_&gt;,而 CQL 解释器需要一个普通的属性访问,而这正是它在错误消息中告诉您的内容。

但你真正(显然)打算做的是调用.Column 的不同重载,它接受两个参数,一个表达式和一个函数。为了防止编译器将第二个函数视为前一个函数体的一部分,您只需在两个函数周围添加括号:

.Column(
   (fun (x : Ranking) -> x.Id),
   (fun (x:ColumnMap)->x.WithName("player_id")) )

或者放在一行:

.Column( (fun (x : Ranking) -> x.Id), (fun (x:ColumnMap)->x.WithName("player_id")) )

【讨论】:

    猜你喜欢
    • 2018-03-13
    • 2012-11-19
    • 2018-07-29
    • 2013-03-16
    • 2016-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-14
    相关资源
    最近更新 更多