2011-12-17 17 views
5

Cercando di ottenere una query con un tipo di lavoro anonimo:Entity Framework e anonimi Tipi in F #

let temporaryBookModel = 
    query <@ context.Books 
    |> Seq.filter (fun book -> book.Id = bookId) 
    |> Seq.map(fun item -> (item.Id, item.ParentUser.Id, item.ParentUser.Alias, item.Tagline, item.Title, item.Visible, item.CreatedDate)) 
    |> Seq.head @> 

E continuo a ricevere:

{ "Solo i costruttori senza parametri e inizializzatori sono supportati in LINQ to Entities. "}

Che avrebbe senso se mappassi direttamente i valori in un tipo, ma i tipi anonimi non dovrebbero lanciare s eccezione che penserei dato che si basano sulla funzionalità di inizializzazione dell'oggetto? Sfortunatamente tutto ciò che ho trovato su tipi anonimi sembra dire che questa è la sintassi corretta. Che o qualcosa di simile:

let temporaryBookModel = 
    query <@ context.Books 
    |> Seq.filter (fun book -> book.Id = bookId) 
    |> Seq.map(fun item -> (("a", item.Id), ("b", item.ParentUser.Id), ("c", item.ParentUser.Alias), ("d", item.Tagline), ("e", item.Title, item.Visible), ("f", item.CreatedDate))) 
    |> Seq.head @> 
+0

F # non ha concetti di 'tipi anonimi' - questa è una caratteristica C#. Qui stai costruendo tuple semplici. – ildjarn

+0

Hai provato a isolare l'errore su un costrutto più specifico (ad esempio, prova Seq.map (fun - I -> i.Id), Seq.map (divertimento i -> i.Id, i.Id)), ecc. .? – fmr

risposta

3

fa F # supporta i tipi anonimi?

Come so, non è così. Ma ci sono 2 modi possibili per soluzioni alternative:

  • uso tuple (come si sta utilizzando)
  • tipi uso di record, ma in questo caso avrete bisogno di definire record prima. Qualcosa di simile a questo:
type Book = 
    { 
     Id: int; 
     ParentId: int; 
     ParentAlias: string; 
     TagLine: string; 
     Title: string; 
     Visible: bool; 
     CreatedDate: DateTime; 
    } 

E codice di utilizzo linea volontà assomiglia:

... 
|> Seq.map 
    (fun item -> 
     { 
      Id = item.Id; 
      ParentId = item.ParentUser.Id; 
      ParentAlias = item.ParentUser.Alias; 
      TagLine = item.Tagline; 
      Title = item.Title; 
      Visible = item.Visible; 
      CreatedDate = item.CreatedDate 
     }) 

Maggiori spiegazioni si possono trovare nella domanda simile here

Aggiornamento:

Record l'utilizzo dei tipi come me è una soluzione più elegante, MA sembra che non funzioni con Entity Framework - F# -> Record with parameterless constructor?.

Quindi, secondo la risposta di Tomas Petricek, deve essere dichiarato tipo esplicito con parametri meno costruttore e proprietà necessarie.