Skip to main content
Version: 0.3.x (0.3.0)

Class ValueObjectDbContextOptionsBuilderExtensions

Namespace: AdCodicem.ValueObjects.EntityFrameworkCore
Assembly: AdCodicem.ValueObjects.EntityFrameworkCore.dll

Adds to the options of a context what the model cannot hold: the translation of what a LINQ query reads of a value object, and the code of the rule a CHECK constraint refused a row under.

public static class ValueObjectDbContextOptionsBuilderExtensions

Inheritance​

object ← ValueObjectDbContextOptionsBuilderExtensions

Inherited Members​

object.Equals(object?), object.Equals(object?, object?), object.GetHashCode(), object.GetType(), object.MemberwiseClone(), object.ReferenceEquals(object?, object?), object.ToString()

Methods​

UseValueObjectCheckErrors(DbContextOptionsBuilder)​

Adds the code of the rule a CHECK constraint of AddValueObjectCheckConstraints refused to the error the database provider throws, under .

public static DbContextOptionsBuilder UseValueObjectCheckErrors(this DbContextOptionsBuilder optionsBuilder)

Parameters​

optionsBuilder DbContextOptionsBuilder

Options builder of the context.

Returns​

DbContextOptionsBuilder

The same builder, so calls can be chained.

Remarks​

The application's own writes pass the constraints, since the value objects it writes went through their rules. A constraint fires for an invalid instance a lax read let in and the application writes back, and for a statement that skips the converter, an ExecuteUpdate setting a column from SQL or raw SQL. Once this is called, the provider's error carries the code of the rule, which reads through the DbUpdateException SaveChanges wraps it in, and from the error ExecuteUpdate, raw SQL or a migration throws as it is: value_object.out_of_range for CK_Orders_Quantity_Minimum. The error is neither replaced nor wrapped, so the catch blocks that handle it keep working.

Entity Framework Core hands no interceptor an error a provider reports while the rows of a query are read. On SQL Server, a raw SQL query that writes rows and reads them back, SqlQuery or FromSql over an INSERT or an UPDATE with OUTPUT, reports a refusal there, so its error carries no code: reads it in a catch. PostgreSQL and SQLite report the refusal of such a query, over RETURNING, as the command runs, and their error carries the code.

The code is read off the name of the constraint, which ends with its rule, as describes, not off the model: a compiled model holds no check constraint, so the code comes with one too. Only an error reporting a violated CHECK constraint is read, on SQL Server, PostgreSQL and SQLite, in every language SQL Server writes its messages in; a migration's error naming a constraint for another reason, "There is already an object named …", carries none. A migration adding a constraint to a table that holds a row it refuses fails with the code, as a write does.

It runs when a command or SaveChanges fails, never when one succeeds; once a command interceptor is registered, though, Entity Framework Core builds the event data of each command it sends, as for any interceptor. It is an interceptor of the options, so it also runs on a service provider of the application's own, named by UseInternalServiceProvider. An interceptor of the application's own registered before it sees the error before the code is added, and Entity Framework Core may log the failure before then too. A second call adds nothing. Without it, reads the code in a catch, from an error whoever sent the command.

Exceptions​

ArgumentNullException

optionsBuilder is null.

UseValueObjectCheckErrors<TContext>(DbContextOptionsBuilder<TContext>)​

Adds the code of the rule a CHECK constraint of AddValueObjectCheckConstraints refused to the error the database provider throws, under .

public static DbContextOptionsBuilder<TContext> UseValueObjectCheckErrors<TContext>(this DbContextOptionsBuilder<TContext> optionsBuilder) where TContext : DbContext

Parameters​

optionsBuilder DbContextOptionsBuilder<TContext>

Options builder of the context.

Returns​

DbContextOptionsBuilder<TContext>

The same builder, so calls can be chained and its options keep the type of the context.

Type Parameters​

TContext

Type of the context.

Remarks​

The same as , for a builder of the options of one context type.

Exceptions​

ArgumentNullException

optionsBuilder is null.

UseValueObjectQueries(DbContextOptionsBuilder)​

Translates .Value of a value object, in a LINQ query, to its column, typed as the underlying value.

public static DbContextOptionsBuilder UseValueObjectQueries(this DbContextOptionsBuilder optionsBuilder)

Parameters​

optionsBuilder DbContextOptionsBuilder

Options builder of the context.

Returns​

DbContextOptionsBuilder

The same builder, so calls can be chained.

Remarks​

Entity Framework Core translates a comparison between value objects, x.Iban == iban, but nothing a query reads of the value one holds: x.Iban.Value.StartsWith("FR") or x.Quantity.Value > 2 fail, as "could not be translated". Once this is called, .Value reads the column itself, under the type mapping of the underlying type for the column's own store type: WHERE [o].[Iban] LIKE N'FR%', which the index on the column serves, and a parameter compared with it is declared as the column is, nvarchar(34). An optional value object, a property inside a JSON column, an element of a primitive collection and a construction of a generic value object are translated too.

Only a property this package maps is translated: through ConfigureValueObjects, HasValueObjectConversion, ConfigureEntityIds or HasEntityIdConversion, whose converters store the bare value, including where Entity Framework Core composes one with its own conversion of the underlying type, a to an int column, say. A property mapped through a converter of the application's own, as a value object over must be, keeps Entity Framework Core's refusal: what its column holds may not be the value. So does this package's converter composed with a conversion of the application's own, except over a type the provider converts itself, a or a , where it cannot be told from Entity Framework Core's composition.

A column of a table is read as it stands. Anything else, the element of a collection, a column an optional navigation joins in, a COALESCE, is converted to the underlying type by a CAST to its own store type, which Entity Framework Core 11 leaves out of the SQL.

.Value reads what the column holds, in a projection too: a strict context, ConfigureValueObjects(strict: true), validates a value object it materializes, not a .Value a query projects. Project the value object to have it validated.

Nothing but .Value is translated: ToString(), which follows the formatting hooks, and EF.Property still fail, and so does .Value of an element of a collection passed as a parameter, which has no type mapping yet when it is translated; a conversion operator stays the cast Entity Framework Core writes, to the unbounded type.

The translation runs once per query shape, which Entity Framework Core caches: nothing more runs per execution. A query precompiled by dotnet ef dbcontext optimize --precompile-queries carries the SQL it wrote, so the options the design-time context is built with call this too, or the precompilation fails on that query. The translator works on a relational provider; with any other, this does nothing.

Entity Framework Core adds the translator to the service provider it builds for the context, never to one the application hands it through UseInternalServiceProvider: a context started on such a provider throws an as it starts, unless the services of the extensions of its options were added to that provider, through IDbContextOptionsExtension.ApplyServices.

Exceptions​

ArgumentNullException

optionsBuilder is null.

UseValueObjectQueries<TContext>(DbContextOptionsBuilder<TContext>)​

Translates .Value of a value object, in a LINQ query, to its column, typed as the underlying value.

public static DbContextOptionsBuilder<TContext> UseValueObjectQueries<TContext>(this DbContextOptionsBuilder<TContext> optionsBuilder) where TContext : DbContext

Parameters​

optionsBuilder DbContextOptionsBuilder<TContext>

Options builder of the context.

Returns​

DbContextOptionsBuilder<TContext>

The same builder, so calls can be chained and its options keep the type of the context.

Type Parameters​

TContext

Type of the context.

Remarks​

The same as , for a builder of the options of one context type.

Exceptions​

ArgumentNullException

optionsBuilder is null.