2011-12-17 15 views
5

Tratando de conseguir una consulta con un tipo de trabajo en el anonimato:de Entity Framework y anónimo Tipos de 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 @> 

Y me siguen dando:

{ "Solamente los constructores sin parámetros y inicializadores son compatibles con LINQ to Entities. "}

Lo que tendría sentido si estuviera mapeando los valores a un tipo directamente, pero los tipos anónimos no deberían arrojar thi s excepción que pensaría ya que se basan en la funcionalidad del inicializador de objetos? Desafortunadamente, todo lo que encontré en tipos anónimos parece decir que esta es la sintaxis correcta. Eso o algo así:

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 # no tiene conceptos de 'tipos anónimos' - esa es una característica de C#. Aquí estás construyendo tuplas simples. – ildjarn

+0

¿Intentó aislar el error en una construcción más específica (es decir, primero intente Seq.map (fun i -> i.Id), Seq.map (fun i -> i.Id, i.Id)), etc. .? – fmr

Respuesta

3

Acción f # es compatible con los tipos anónimos?

Como sé, no es así. Sin embargo, hay 2 maneras posibles para soluciones:

  • tuplas de uso (como usted está utilizando)
  • tipos de registro de uso, pero en este caso se deberá definir registro antes. Algo como esto:
type Book = 
    { 
     Id: int; 
     ParentId: int; 
     ParentAlias: string; 
     TagLine: string; 
     Title: string; 
     Visible: bool; 
     CreatedDate: DateTime; 
    } 

Y código de uso de la línea se verá como:

... 
|> 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 
     }) 

Más explicaciones se pueden encontrar en la pregunta similar here

Actualización:

Registro el uso de tipos como para mí es una solución más elegante, PERO parece que no funciona con Entity Framework - F# -> Record with parameterless constructor?.

Por lo tanto, de acuerdo con la respuesta de Tomas Petricek - tiene que ser declarado tipo explícito con parámetros menos el constructor y las propiedades necesarias.