5

This is another take on accessing dynamic objects in F# There I'm using let y = x.Where(fun x -> x.City ="London").Select("new(City,Zip)") to parametrize the query and extract the necessary items. These would correspond to columns in an SQL query, and be represented by a property of the datacontext. This is the part that I would like to pass in as a parameter.

type Northwind = ODataService<"http://services.odata.org/Northwind/Northwind.svc">
let db = Northwind.GetDataContext()
let query2 = query { for customer in db.Customers do
                     select customer}  |> Seq.toArray
let qryfun (x:Northwind.ServiceTypes.Customer) =
    query { for x in query2 do
            select (x.City,x.CompanyName,x.Country)}

Basically I would like to pass in not only x but also x.*. As I'm accessing one database that is fixed, I can factor out x. However I now have 40 small functions extracting the different columns. Is it possible to factor it out to one function and pass the property as an argument? So sometimes I extractx.City but other times x.Country. I have tried using quotations however cannot splice it properly and maybe that is not the right approach.

Community
  • 1
  • 1
s952163
  • 6,276
  • 4
  • 23
  • 47
  • I think you can just return tuple from the query like `select (customer, customer.City)` and your `qryfun` will accept tuple as a parameter Since all variety of customer properties dont have static type, you either use tuples for intermediate data flow between functions/transformations or define your own record type and map it in your query – paulik Apr 11 '16 at 15:31
  • @paulik thx. I'm not sure that is doable. E.g. `let qryfun (x, x.column) = query { for x in query2 do select (x.column)}` where x is the DB table (Northwind.ServiceTypes.Customer) and x.column is a Column (or field) in the Customer table, it could be x.City, x.Country, etc.... then I would call `qryfun (Northwind.ServiceTypes.Customer, Northwind.ServiceTypes.Customer.City)` The 2nd argument is tricky because Northwind.ServiceTypes.Customer.City belongs to each record not to the table. If you take a look at the referenced question, I bult it from a string ("new(City, Country)") – s952163 Apr 11 '16 at 23:21

1 Answers1

7

Regarding quotation splicing, this works for me:

open System.Linq

type record = { x:int; y:string }

let mkQuery q =
    query {
        for x in [{x=1;y="test"}].AsQueryable() do
        select ((%q) x)
    }

mkQuery <@ fun r -> r.x, r.y @>
|> Seq.iter (printfn "%A")
kvb
  • 54,864
  • 2
  • 91
  • 133