Преобразование типов F # - PullRequest
0 голосов
/ 26 апреля 2019

У меня есть дискриминированные союзы, подобные этому

type AbcJson = JsonProvider<"""
{
    "Id": 1234,
    "List": [
          {
            "BT": "abc",
            "Year": 2019,
            "A": 9223372036854775806
          },
          {
            "BT": "bottomUp",
            "Year": 2019
          }
        ]
}
""">

type Event =
    | Cdf of CdfJson.Root
    | Abc of AbcJson.Root

У меня также есть функция, которая возвращает значение из db

type g = SqlCommandProvider<"
            Select [BT], [Year], [A] from dbo.Abc;
            " , connectionString>

let dbGet = 
    use cmd = new g(connectionString)
    let data = cmd.Execute() 
    data |> Seq.toArray

let data = dbGet
printfn "%A" data 
// [|{ BT = "abc"; Year = 2019; A = Some 1L };
//   { BT = "abc"; Year = 2019; A = None }|] 

Но когда я пытаюсь сделать это

let q = Abc(AbcJson.Root(1002, data));

Я получаю такую ​​ошибку

Type mismatch. Expecting a
'JsonProvider‹...>.List []'
but given a 'SqlCommandProvider<...>.Record []'
The type 'JsonProvider‹...>.List' does not match the type 
'SqICommandProvider<...>.Record'

Я не могу разыграть SqlCommandProvider<...>.Record [] to JsonProvider‹...>.List [].Что я могу сделать, чтобы разыграть SqlCommandProvider<...>.Record [] to JsonProvider‹...>.List []?Некоторая справка или документ будут действительно полезны.

1 Ответ

2 голосов
/ 26 апреля 2019

В вашем коде вы получаете совместимые данные из двух источников - как источника JSON, так и базы данных. Однако JsonProvider и SqlCommandProviders генерируют два разных типа для хранения этих данных. JsonProvider создает свою собственную запись, а SqlCommandProvider создает свою собственную запись. Две разные записи могут иметь одинаковые члены, но вы не сможете «привести» одну к другой, не копируя данные из одного типа в другой тип.

Хотя вы можете скопировать данные из записи SqlCommandProvider в запись JsonProvider, я не уверен, что это будет лучшим подходом. Поставщики типа F # действительно удобны для создания записей, соответствующих заданным данным. Однако, в вашем случае, вы можете рассмотреть возможность создания своей собственной записи. Как то так ...

type AbcData {
   string: BT
   int: Year
   long option: A }

... в который вы сохраняете данные как из источника JSON, так и из базы данных.

Затем вы скопируете данные, поступающие из записи JsonProvider, в ваш тип записи и скопируете данные, поступающие из записи SqlCommandProvider, в ваш тип записи. Таким образом, тип вашей записи является общим местом назначения для данных JSON и базы данных.

...