F #: In LINQ, only constructors and initializers without parameters are supported for objects

I am trying to return Envelope from a request. The envelope is defined as follows.

[<CLIMutable>]
type Envelope<'T> = {
    Id : Guid
    StreamId: Guid
    Created : DateTimeOffset
    Item : 'T }

MyLibAAS.DataStore.MyLibAASDbContext is an EF DbContext written in C #. When I extend it to f # as follows, I get an error:Only parameterless constructors and initializers are supported in LINQ to Entities.

type MyLibAAS.DataStore.MyLibAASDbContext with 
    member this.GetEvents streamId = 
        query {
            for event in this.Events do
            where (event.StreamId = streamId)
            select {
                Id = event.Id;
                StreamId = streamId;
                Created = event.Timestamp;
                Item = (JsonConvert.DeserializeObject<QuestionnaireEvent> event.Payload)
            }
        } 

If I get my event back and list it in Envelope after the fact, it works fine.

type MyLibAAS.DataStore.MyLibAASDbContext with 
    member this.GetEvents streamId = 
        query {
            for event in this.Events do
            where (event.StreamId = streamId)
            select event
        } |> Seq.map (fun event ->
                {
                    Id = event.Id
                    StreamId = streamId
                    Created = event.Timestamp
                    Item = (JsonConvert.DeserializeObject<QuestionnaireEvent> event.Payload)
                }
            )

Why does it matter? The type of envelope is not even type EF.

+4
source share
2 answers

F #
F # .NET- , ( ).
, # :

public class Envelope<T> : IComparable<Envelope<T>>, IEquatable<Envelope<T>>, ...
{
   public Guid Id { get; private set; }
   public Guid StreamId { get; private set; }
   public DateTimeOffset Created { get; private set; }
   public T Item { get; private set; }

   public Envelope( Guid id, Guid streamId, DateTimeOffset created, T item ) {
      this.Id = id;
      this.StreamId = streamId;
      this.Created = created;
      this.Item = item;
   }

   // Plus implementations of IComparable, IEquatable, etc.
}

F #, F # , .
, select # :

select new Envelope<QuestionnaireEvent>( 
   event.Id, streamId, event.Timestamp, 
   JsonConvert.DeserializeObject<QuestionnaireEvent>(event.Payload) )

Entity Framework
, Entity Framework . : , :

from e in ...
let env = new Envelope<E>( e.Id, ... )
where env.Id > 0
select env

Entity Framework , , , e.Id, , env.Id. F #, .NET.
Entity Framework, , , Envelope F # . . , Entity Framework F # .
( : # , EF )


, Envelope . - , :

type Envelope<'T>() =
   member val Id : Guid = Guid.Empty with get, set
   member val StreamId : Guid = Guid.Empty with get, set
   member val Created : DateTimeOffset = DateTimeOffset.MinValue with get, set
   member val Item : 'T = Unchecked.defaultof<'T> with get, set

:

select Envelope<_>( Id = event.Id, StreamId = streamId, ... )

select Seq.map
Seq.map . IQueryable, SQL Entity Framework. EF , query, SQL Server. Seq.map .
Seq.map CLR, SQL, , , , .
"" : , , Event . , .

,
, Envelope ( ), : JsonConvert.DeserializeObject SQL, Entity Framework . , , - CLR, , SQL.

+5

LINQ to Entities, , query, , . .

, Entity Framework Envelope<'T>, SQL . , , .NET - , , .

EF , POCO event , Seq.map ping fancy Envelope s, , .NET.

: , ? , MsgBox() ? , , ( ), , .

. F # , .

+2

All Articles