Single case union types (aka Simple types)
It's common to use single case discriminated unions to meaningfully represent data values. But EF does not know anything about this kind of type. Luckily this repository has some ways to help you to deal with they.
Configuring
We have two approaches to deal with single case union types which are a converter or an extension that searches for all Single Case Unions in your entities.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: |
|
Querying
You can query for equality without any problem
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: |
|
For querying with other types of operation you will need to unwrap the value inside the query
1: 2: 3: 4: 5: 6: 7: 8: |
|
Private Constructor
This extension doesn't support private union case constructors.
namespace EntityFrameworkCore
namespace EntityFrameworkCore.FSharp
module Extensions
from EntityFrameworkCore.FSharp
from EntityFrameworkCore.FSharp
Multiple items
union case PositiveInteger.PositiveInteger: int -> PositiveInteger
--------------------
type PositiveInteger = | PositiveInteger of int
union case PositiveInteger.PositiveInteger: int -> PositiveInteger
--------------------
type PositiveInteger = | PositiveInteger of int
Multiple items
val int : value:'T -> int (requires member op_Explicit)
--------------------
type int = int32
--------------------
type int<'Measure> = int
val int : value:'T -> int (requires member op_Explicit)
--------------------
type int = int32
--------------------
type int<'Measure> = int
Multiple items
type CLIMutableAttribute =
inherit Attribute
new : unit -> CLIMutableAttribute
--------------------
new : unit -> CLIMutableAttribute
type CLIMutableAttribute =
inherit Attribute
new : unit -> CLIMutableAttribute
--------------------
new : unit -> CLIMutableAttribute
type Blog =
{ Id: Guid
Title: string
Votes: PositiveInteger }
{ Id: Guid
Title: string
Votes: PositiveInteger }
Multiple items
type KeyAttribute =
inherit Attribute
new : unit -> KeyAttribute
--------------------
KeyAttribute() : KeyAttribute
type KeyAttribute =
inherit Attribute
new : unit -> KeyAttribute
--------------------
KeyAttribute() : KeyAttribute
Blog.Id: Guid
Multiple items
type Guid =
struct
new : b:byte[] -> Guid + 5 overloads
member CompareTo : value:obj -> int + 1 overload
member Equals : o:obj -> bool + 1 overload
member GetHashCode : unit -> int
member ToByteArray : unit -> byte[]
member ToString : unit -> string + 2 overloads
member TryFormat : destination:Span<char> * charsWritten:int * ?format:ReadOnlySpan<char> -> bool
member TryWriteBytes : destination:Span<byte> -> bool
static val Empty : Guid
static member NewGuid : unit -> Guid
...
end
--------------------
Guid ()
Guid(b: byte []) : Guid
Guid(b: ReadOnlySpan<byte>) : Guid
Guid(g: string) : Guid
Guid(a: int, b: int16, c: int16, d: byte []) : Guid
Guid(a: uint32, b: uint16, c: uint16, d: byte, e: byte, f: byte, g: byte, h: byte, i: byte, j: byte, k: byte) : Guid
Guid(a: int, b: int16, c: int16, d: byte, e: byte, f: byte, g: byte, h: byte, i: byte, j: byte, k: byte) : Guid
type Guid =
struct
new : b:byte[] -> Guid + 5 overloads
member CompareTo : value:obj -> int + 1 overload
member Equals : o:obj -> bool + 1 overload
member GetHashCode : unit -> int
member ToByteArray : unit -> byte[]
member ToString : unit -> string + 2 overloads
member TryFormat : destination:Span<char> * charsWritten:int * ?format:ReadOnlySpan<char> -> bool
member TryWriteBytes : destination:Span<byte> -> bool
static val Empty : Guid
static member NewGuid : unit -> Guid
...
end
--------------------
Guid ()
Guid(b: byte []) : Guid
Guid(b: ReadOnlySpan<byte>) : Guid
Guid(g: string) : Guid
Guid(a: int, b: int16, c: int16, d: byte []) : Guid
Guid(a: uint32, b: uint16, c: uint16, d: byte, e: byte, f: byte, g: byte, h: byte, i: byte, j: byte, k: byte) : Guid
Guid(a: int, b: int16, c: int16, d: byte, e: byte, f: byte, g: byte, h: byte, i: byte, j: byte, k: byte) : Guid
Blog.Title: string
Multiple items
val string : value:'T -> string
--------------------
type string = String
val string : value:'T -> string
--------------------
type string = String
Blog.Votes: PositiveInteger
Multiple items
type MyContext =
inherit DbContext
new : unit -> MyContext
val mutable private _blogs: DbSet<Blog>
override OnConfiguring : options:DbContextOptionsBuilder -> unit
override OnModelCreating : builder:ModelBuilder -> unit
member Blogs : DbSet<Blog>
member Blogs : DbSet<Blog> with set
--------------------
new : unit -> MyContext
type MyContext =
inherit DbContext
new : unit -> MyContext
val mutable private _blogs: DbSet<Blog>
override OnConfiguring : options:DbContextOptionsBuilder -> unit
override OnModelCreating : builder:ModelBuilder -> unit
member Blogs : DbSet<Blog>
member Blogs : DbSet<Blog> with set
--------------------
new : unit -> MyContext
Multiple items
type DbContext =
new : options:DbContextOptions -> DbContext
member Add<'TEntity> : entity:'TEntity -> EntityEntry<'TEntity> + 1 overload
member AddAsync<'TEntity> : entity:'TEntity * ?cancellationToken:CancellationToken -> ValueTask<EntityEntry<'TEntity>> + 1 overload
member AddRange : [<ParamArray>] entities:obj[] -> unit + 1 overload
member AddRangeAsync : [<ParamArray>] entities:obj[] -> Task + 1 overload
member Attach<'TEntity> : entity:'TEntity -> EntityEntry<'TEntity> + 1 overload
member AttachRange : [<ParamArray>] entities:obj[] -> unit + 1 overload
member ChangeTracker : ChangeTracker
member ContextId : DbContextId
member Database : DatabaseFacade
...
--------------------
DbContext() : DbContext
DbContext(options: DbContextOptions) : DbContext
type DbContext =
new : options:DbContextOptions -> DbContext
member Add<'TEntity> : entity:'TEntity -> EntityEntry<'TEntity> + 1 overload
member AddAsync<'TEntity> : entity:'TEntity * ?cancellationToken:CancellationToken -> ValueTask<EntityEntry<'TEntity>> + 1 overload
member AddRange : [<ParamArray>] entities:obj[] -> unit + 1 overload
member AddRangeAsync : [<ParamArray>] entities:obj[] -> Task + 1 overload
member Attach<'TEntity> : entity:'TEntity -> EntityEntry<'TEntity> + 1 overload
member AttachRange : [<ParamArray>] entities:obj[] -> unit + 1 overload
member ChangeTracker : ChangeTracker
member ContextId : DbContextId
member Database : DatabaseFacade
...
--------------------
DbContext() : DbContext
DbContext(options: DbContextOptions) : DbContext
Multiple items
type DefaultValueAttribute =
inherit Attribute
new : unit -> DefaultValueAttribute
new : check:bool -> DefaultValueAttribute
member Check : bool
--------------------
new : unit -> DefaultValueAttribute
new : check:bool -> DefaultValueAttribute
type DefaultValueAttribute =
inherit Attribute
new : unit -> DefaultValueAttribute
new : check:bool -> DefaultValueAttribute
member Check : bool
--------------------
new : unit -> DefaultValueAttribute
new : check:bool -> DefaultValueAttribute
MyContext._blogs: DbSet<Blog>
type DbSet<'TEntity (requires reference type)> =
member Add : entity:'TEntity -> EntityEntry<'TEntity>
member AddAsync : entity:'TEntity * ?cancellationToken:CancellationToken -> ValueTask<EntityEntry<'TEntity>>
member AddRange : [<ParamArray>] entities:'TEntity[] -> unit + 1 overload
member AddRangeAsync : [<ParamArray>] entities:'TEntity[] -> Task + 1 overload
member AsAsyncEnumerable : unit -> IAsyncEnumerable<'TEntity>
member AsQueryable : unit -> IQueryable<'TEntity>
member Attach : entity:'TEntity -> EntityEntry<'TEntity>
member AttachRange : [<ParamArray>] entities:'TEntity[] -> unit + 1 overload
member EntityType : IEntityType
member Equals : obj:obj -> bool
...
member Add : entity:'TEntity -> EntityEntry<'TEntity>
member AddAsync : entity:'TEntity * ?cancellationToken:CancellationToken -> ValueTask<EntityEntry<'TEntity>>
member AddRange : [<ParamArray>] entities:'TEntity[] -> unit + 1 overload
member AddRangeAsync : [<ParamArray>] entities:'TEntity[] -> Task + 1 overload
member AsAsyncEnumerable : unit -> IAsyncEnumerable<'TEntity>
member AsQueryable : unit -> IQueryable<'TEntity>
member Attach : entity:'TEntity -> EntityEntry<'TEntity>
member AttachRange : [<ParamArray>] entities:'TEntity[] -> unit + 1 overload
member EntityType : IEntityType
member Equals : obj:obj -> bool
...
val this : MyContext
val set : elements:seq<'T> -> Set<'T> (requires comparison)
val v : DbSet<Blog>
val builder : ModelBuilder
ModelBuilder.Entity<'TEntity (requires reference type)>() : Metadata.Builders.EntityTypeBuilder<'TEntity>
ModelBuilder.Entity<'TEntity (requires reference type)>(buildAction: Action<Metadata.Builders.EntityTypeBuilder<'TEntity>>) : ModelBuilder
ModelBuilder.Entity(name: string) : Metadata.Builders.EntityTypeBuilder
ModelBuilder.Entity(type: Type) : Metadata.Builders.EntityTypeBuilder
ModelBuilder.Entity(name: string, buildAction: Action<Metadata.Builders.EntityTypeBuilder>) : ModelBuilder
ModelBuilder.Entity(type: Type, buildAction: Action<Metadata.Builders.EntityTypeBuilder>) : ModelBuilder
ModelBuilder.Entity<'TEntity (requires reference type)>(buildAction: Action<Metadata.Builders.EntityTypeBuilder<'TEntity>>) : ModelBuilder
ModelBuilder.Entity(name: string) : Metadata.Builders.EntityTypeBuilder
ModelBuilder.Entity(type: Type) : Metadata.Builders.EntityTypeBuilder
ModelBuilder.Entity(name: string, buildAction: Action<Metadata.Builders.EntityTypeBuilder>) : ModelBuilder
ModelBuilder.Entity(type: Type, buildAction: Action<Metadata.Builders.EntityTypeBuilder>) : ModelBuilder
val x : Blog
Multiple items
type SingleCaseUnionConverter<'T,'U> =
inherit ValueConverter<'U,'T>
new : unit -> SingleCaseUnionConverter<'T,'U>
--------------------
new : unit -> SingleCaseUnionConverter<'T,'U>
type SingleCaseUnionConverter<'T,'U> =
inherit ValueConverter<'U,'T>
new : unit -> SingleCaseUnionConverter<'T,'U>
--------------------
new : unit -> SingleCaseUnionConverter<'T,'U>
val ignore : value:'T -> unit
member ModelBuilder.RegisterSingleUnionCases : unit -> unit
val options : DbContextOptionsBuilder
Multiple items
type DbContextOptionsBuilder =
new : unit -> DbContextOptionsBuilder + 1 overload
member AddInterceptors : interceptors:IEnumerable<IInterceptor> -> DbContextOptionsBuilder + 1 overload
member ConfigureLoggingCacheTime : timeSpan:TimeSpan -> DbContextOptionsBuilder
member ConfigureWarnings : warningsConfigurationBuilderAction:Action<WarningsConfigurationBuilder> -> DbContextOptionsBuilder
member EnableDetailedErrors : ?detailedErrorsEnabled:bool -> DbContextOptionsBuilder
member EnableSensitiveDataLogging : ?sensitiveDataLoggingEnabled:bool -> DbContextOptionsBuilder
member EnableServiceProviderCaching : ?cacheServiceProvider:bool -> DbContextOptionsBuilder
member EnableThreadSafetyChecks : ?enableChecks:bool -> DbContextOptionsBuilder
member Equals : obj:obj -> bool
member GetHashCode : unit -> int
...
--------------------
type DbContextOptionsBuilder<'TContext (requires 'TContext :> DbContext)> =
inherit DbContextOptionsBuilder
new : unit -> DbContextOptionsBuilder<'TContext> + 1 overload
member AddInterceptors : interceptors:IEnumerable<IInterceptor> -> DbContextOptionsBuilder<'TContext> + 1 overload
member ConfigureLoggingCacheTime : timeSpan:TimeSpan -> DbContextOptionsBuilder<'TContext>
member ConfigureWarnings : warningsConfigurationBuilderAction:Action<WarningsConfigurationBuilder> -> DbContextOptionsBuilder<'TContext>
member EnableDetailedErrors : ?detailedErrorsEnabled:bool -> DbContextOptionsBuilder<'TContext>
member EnableSensitiveDataLogging : ?sensitiveDataLoggingEnabled:bool -> DbContextOptionsBuilder<'TContext>
member EnableServiceProviderCaching : ?cacheServiceProvider:bool -> DbContextOptionsBuilder<'TContext>
member EnableThreadSafetyChecks : ?checksEnabled:bool -> DbContextOptionsBuilder<'TContext>
member LogTo : filter:Func<EventId, LogLevel, bool> * logger:Action<EventData> -> DbContextOptionsBuilder<'TContext> + 4 overloads
member Options : DbContextOptions<'TContext>
...
--------------------
DbContextOptionsBuilder() : DbContextOptionsBuilder
DbContextOptionsBuilder(options: DbContextOptions) : DbContextOptionsBuilder
--------------------
DbContextOptionsBuilder() : DbContextOptionsBuilder<'TContext>
DbContextOptionsBuilder(options: DbContextOptions<'TContext>) : DbContextOptionsBuilder<'TContext>
type DbContextOptionsBuilder =
new : unit -> DbContextOptionsBuilder + 1 overload
member AddInterceptors : interceptors:IEnumerable<IInterceptor> -> DbContextOptionsBuilder + 1 overload
member ConfigureLoggingCacheTime : timeSpan:TimeSpan -> DbContextOptionsBuilder
member ConfigureWarnings : warningsConfigurationBuilderAction:Action<WarningsConfigurationBuilder> -> DbContextOptionsBuilder
member EnableDetailedErrors : ?detailedErrorsEnabled:bool -> DbContextOptionsBuilder
member EnableSensitiveDataLogging : ?sensitiveDataLoggingEnabled:bool -> DbContextOptionsBuilder
member EnableServiceProviderCaching : ?cacheServiceProvider:bool -> DbContextOptionsBuilder
member EnableThreadSafetyChecks : ?enableChecks:bool -> DbContextOptionsBuilder
member Equals : obj:obj -> bool
member GetHashCode : unit -> int
...
--------------------
type DbContextOptionsBuilder<'TContext (requires 'TContext :> DbContext)> =
inherit DbContextOptionsBuilder
new : unit -> DbContextOptionsBuilder<'TContext> + 1 overload
member AddInterceptors : interceptors:IEnumerable<IInterceptor> -> DbContextOptionsBuilder<'TContext> + 1 overload
member ConfigureLoggingCacheTime : timeSpan:TimeSpan -> DbContextOptionsBuilder<'TContext>
member ConfigureWarnings : warningsConfigurationBuilderAction:Action<WarningsConfigurationBuilder> -> DbContextOptionsBuilder<'TContext>
member EnableDetailedErrors : ?detailedErrorsEnabled:bool -> DbContextOptionsBuilder<'TContext>
member EnableSensitiveDataLogging : ?sensitiveDataLoggingEnabled:bool -> DbContextOptionsBuilder<'TContext>
member EnableServiceProviderCaching : ?cacheServiceProvider:bool -> DbContextOptionsBuilder<'TContext>
member EnableThreadSafetyChecks : ?checksEnabled:bool -> DbContextOptionsBuilder<'TContext>
member LogTo : filter:Func<EventId, LogLevel, bool> * logger:Action<EventData> -> DbContextOptionsBuilder<'TContext> + 4 overloads
member Options : DbContextOptions<'TContext>
...
--------------------
DbContextOptionsBuilder() : DbContextOptionsBuilder
DbContextOptionsBuilder(options: DbContextOptions) : DbContextOptionsBuilder
--------------------
DbContextOptionsBuilder() : DbContextOptionsBuilder<'TContext>
DbContextOptionsBuilder(options: DbContextOptions<'TContext>) : DbContextOptionsBuilder<'TContext>
type unit = Unit
val blog : Blog
val query : Linq.QueryBuilder
val ctx : MyContext
property MyContext.Blogs: DbSet<Blog> with get, set
custom operation: where (bool)
Calls Linq.QueryBuilder.Where
Calls Linq.QueryBuilder.Where
custom operation: select ('Result)
Calls Linq.QueryBuilder.Select
Calls Linq.QueryBuilder.Select
custom operation: headOrDefault
Calls Linq.QueryBuilder.HeadOrDefault
Calls Linq.QueryBuilder.HeadOrDefault
val blog' : Blog
(extension) Collections.Generic.IEnumerable.Where<'TSource>(predicate: Func<'TSource,bool>) : Collections.Generic.IEnumerable<'TSource>
(extension) Collections.Generic.IEnumerable.Where<'TSource>(predicate: Func<'TSource,int,bool>) : Collections.Generic.IEnumerable<'TSource>
(extension) IQueryable.Where<'TSource>(predicate: Expressions.Expression<Func<'TSource,bool>>) : IQueryable<'TSource>
(extension) IQueryable.Where<'TSource>(predicate: Expressions.Expression<Func<'TSource,int,bool>>) : IQueryable<'TSource>
(extension) Collections.Generic.IEnumerable.Where<'TSource>(predicate: Func<'TSource,int,bool>) : Collections.Generic.IEnumerable<'TSource>
(extension) IQueryable.Where<'TSource>(predicate: Expressions.Expression<Func<'TSource,bool>>) : IQueryable<'TSource>
(extension) IQueryable.Where<'TSource>(predicate: Expressions.Expression<Func<'TSource,int,bool>>) : IQueryable<'TSource>
val b : Blog
val blogQuery : Blog
val votes : int