हाल ही में मैंने टाइप प्रदाताओं पर कीथ बटोतोई द्वारा एक ट्यूटोरियल में भाग लिया, जिसमें उन्होंने एमएसडीएन ट्यूटोरियल में मिनीसीएसवी प्रकार प्रदाता का एक संस्करण पेश किया। दुर्भाग्यवश, मेरा लैपटॉप उपलब्ध नहीं था, इसलिए मुझे हाथ से कोड लिखना पड़ा और साथ ही मैं कर सकता था। मेरा मानना है कि मैं प्रकार प्रदाता निर्मित किया है, लेकिन मैंएफ # कस्टम प्रकार प्रदाता: "कंटेनर प्रकार पहले से सेट है" त्रुटि
error FS3033: The type provider 'CsvFileTypeProvider+CsvFileTypeProvider' reported an error: container type for 'CsvFileProvider.Row' was already set to 'CsvFileProvider.CsvFile,Filename="events.csv"
हो रही है जब मैं कोड को देखो, मैं नहीं देख सकते हैं कि मैं दो बार कंटेनर के लिए पंक्ति प्रकार जोड़ रहा है (या कुछ करने के लिए अन्य कंटेनर)। कोड की चयनित लाइनों को हटाने से मदद नहीं मिलती है।
यहाँ कैसे मैं FSI में कोड फोन कर रहा हूँ है:
#r "CsvFileTypeProvider.dll"
open CsvFileProvider
let eventInfos = new CsvFile<"events.csv">() ;;
और यहाँ कोड में ही है:
module CsvFileTypeProvider
open Samples.FSharp.ProvidedTypes
open Microsoft.FSharp.Core.CompilerServices
let getType str =
if System.DateTime.TryParse(str, ref Unchecked.defaultof<_>) then
typeof<System.DateTime>, (fun (str:Quotations.Expr) -> <@@ System.DateTime.Parse(%%str) @@>)
elif System.Int32.TryParse(str, ref Unchecked.defaultof<_>) then
typeof<System.Int32>, (fun (str:Quotations.Expr) -> <@@ System.Int32.Parse(%%str) @@>)
elif System.Double.TryParse(str, ref Unchecked.defaultof<_>) then
typeof<System.Double>, (fun (str:Quotations.Expr) -> <@@ System.Double.Parse(%%str) @@>)
else
typeof<string>, (fun (str:Quotations.Expr) -> <@@ %%str @@>)
[<TypeProvider>]
type CsvFileTypeProvider() =
inherit TypeProviderForNamespaces()
let asm = typeof<CsvFileTypeProvider>.Assembly
let ns = "CsvFileProvider"
let csvFileProviderType = ProvidedTypeDefinition(asm, ns, "CsvFile", None)
let parameters = [ProvidedStaticParameter("Filename", typeof<string>)]
do csvFileProviderType.DefineStaticParameters(parameters, fun tyName [| :? string as filename |] ->
let rowType = ProvidedTypeDefinition(asm, ns, "Row", Some(typeof<string[]>))
let lines = System.IO.File.ReadLines(filename) |> Seq.map (fun line -> line.Split(','))
let columnNames = lines |> Seq.nth 0
let resultTypes = lines |> Seq.nth 1 |> Array.map getType
for idx in 0 .. (columnNames.Length - 1) do
let col = columnNames.[idx]
let ty, converter = resultTypes.[idx]
let prop = ProvidedProperty(col, ty)
prop.GetterCode <- fun [row] -> converter <@@ (%%row:string[]).[idx] @@>
rowType.AddMember(prop)
let wholeFileType = ProvidedTypeDefinition(asm, ns, tyName, Some(typedefof<seq<_>>.MakeGenericType(rowType)))
wholeFileType.AddMember(rowType)
let ctor = ProvidedConstructor(parameters = []) // the *type* is parameterized but the *constructor* gets no args
ctor.InvokeCode <- //given the inputs, what will we get as the outputs? Now we want to read the *data*, skip the header
fun [] -> <@@ System.IO.File.ReadLines(filename) |> Seq.skip 1 |> Seq.map (fun line -> line.Split(',')) @@>
wholeFileType.AddMember(ctor)
wholeFileType
)
do base.AddNamespace(ns, [csvFileProviderType])
[<TypeProviderAssembly>]
do()
किसी भी मदद के लिए धन्यवाद!
धन्यवाद! मदद की सराहना करें। –