Here the discriminator configuration in the DbContext
modelBuilder.Entity<Payment>().HasDiscriminator(p => p.PaymentType)
//.HasValue<Payment>(EnumPaymentType.PAYMENT)
.HasValue<CreditCard>(EnumPaymentType.CREDIT_CARD)
.HasValue<Cash>(EnumPaymentType.CASH)
.HasValue<BankCheck>(EnumPaymentType.BANK_CHECK)
.HasValue<BankTransfer>(EnumPaymentType.BANK_TRANSFER);
Here the project.json
{
"authors": [
"Cedalis"
],
"description": "Application Intranet de gestion des formations pour médiateur",
"version": "1.0.0",
"buildOptions": {
"emitEntryPoint": true
},
"dependencies": {
"Microsoft.EntityFrameworkCore.Tools": {
"type": "build",
"version": "1.0.0-preview1-final"
},
"Microsoft.EntityFrameworkCore": "1.0.0-rc2-final",
"Microsoft.AspNetCore.Server.Kestrel": "1.0.0-rc2-final",
"Microsoft.AspNetCore.Diagnostics": "1.0.0-rc2-final",
"Microsoft.AspNetCore.Hosting": "1.0.0-rc2-final",
"Microsoft.AspNetCore.Identity.EntityFrameworkCore": "1.0.0-rc2-final",
"Microsoft.AspNetCore.Mvc": "1.0.0-rc2-final",
"Microsoft.AspNetCore.Mvc.Formatters.Json": "1.0.0-rc2-final",
"Microsoft.AspNetCore.Mvc.TagHelpers": "1.0.0-rc2-final",
"Microsoft.AspNetCore.Routing": "1.0.0-rc2-final",
"Microsoft.AspNetCore.StaticFiles": "1.0.0-rc2-final",
"Microsoft.Extensions.Logging.Console": "1.0.0-rc2-final",
"Microsoft.Extensions.Configuration.CommandLine": "1.0.0-rc2-final",
"Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0-rc2-final",
"Microsoft.Extensions.Configuration.Json": "1.0.0-rc2-final",
"Npgsql.EntityFrameworkCore.PostgreSQL": "1.0.0-rc2-*",
"Npgsql.EntityFrameworkCore.PostgreSQL.Design": "1.0.0-rc2-*",
"Npgsql": "3.1.0-*",
"Newtonsoft.Json": "8.0.3",
"JetBrains.Annotations": "10.1.4"
},
"frameworks": {
"netcoreapp1.0": {
"imports": ["portable-net451+win8"]
}
},
"runtimes": {
"debian.8.2-x64": {}
},
"tools": {
"Microsoft.EntityFrameworkCore.Tools": {
"imports": ["portable-net451+win8"],
"version": "1.0.0-preview1-final"
}
}
}
I get this error with the ef database update command below when the class base is undefined with his own type enum, see the commented line
error CS1503: Argument 1: cannot convert from 'string' to 'short'
and here the discrimator generated in the designer file
b.HasDiscriminator<short>("PaymentType").HasValue("Payment"); // string in place of enum
Here the discrimator generated in the designer file when i uncommented the discrimator for the class base
b.HasDiscriminator<short>("PaymentType").HasValue(EnumPaymentType.PAYMENT);
// Ok the command use the enum type but the explicit cast is missing
and the error message
cannot convert from 'Mediagral.Accounting.Models.EnumPaymentType' to 'short'
of course, I have the same problem with the other migration file snapshot.
Also once i corrected the cast, i get the exception below
System.InvalidOperationException: Cannot set discriminator value 'BANK_CHECK' for discriminator property 'PaymentType' because it is not assignable to property of type 'System.Int16'.
at Microsoft.EntityFrameworkCore.Metadata.RelationalEntityTypeAnnotations.SetDiscriminatorValue(Object value)
at Microsoft.EntityFrameworkCore.Metadata.Builders.DiscriminatorBuilder.HasValue(InternalEntityTypeBuilder entityTypeBuilder, Object value)
at EntitiesEF.Migrations.initial.<>c.<BuildTargetModel>b__0_80(EntityTypeBuilder b)
at Microsoft.EntityFrameworkCore.ModelBuilder.Entity(String name, Action`1 buildAction)
at EntitiesEF.Migrations.initial.BuildTargetModel(ModelBuilder modelBuilder)
at Microsoft.EntityFrameworkCore.Migrations.Migration.<.ctor>b__4_0()
at Microsoft.EntityFrameworkCore.Internal.LazyRef`1.get_Value()
at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.GenerateUpSql(Migration migration)
at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.Migrate(String targetMigration)
at Microsoft.EntityFrameworkCore.Design.MigrationsOperations.UpdateDatabase(String targetMigration, String contextType)
at Microsoft.EntityFrameworkCore.Tools.Cli.DatabaseUpdateCommand.<>c__DisplayClass0_0.<Configure>b__0()
at Microsoft.Extensions.CommandLineUtils.CommandLineApplication.Execute(String[] args)
at Microsoft.EntityFrameworkCore.Tools.Cli.Program.Main(String[] args)
Cannot set discriminator value 'BANK_CHECK' for discriminator property 'PaymentType' because it is not assignable to property of type 'System.Int16'.
The error is throw because the others entities derivated are also not casted in the migration file.
Here the enum declaration
namespace Mediagral.Accounting.Models
{
public enum EnumPaymentType : short
{
PAYMENT,
CREDIT_CARD,
CASH,
BANK_TRANSFER,
BANK_CHECK
}
}
EF Core version 1.0 rc2 final with Npgsql
Operating system debian 8
framework target netcoreapp1.0
FWIW, the repro we obtained for #5406 also shows the case in which we generated a discriminator value of the enum type, e.g. b.HasDiscriminator<short>("PaymentType").HasValue(EnumPaymentType.PAYMENT).
@AndriySvyryd is this something we could fix for RTM? Or should we consider other options?
cc @rowanmiller
According to #4061, we encountered similar issue on Default value. The value was Enum type and which Migration doesn't (& shouldn't) import. The fix we applied there was to store underlying value in annotation for default value. Probably something similar we can do when storing discriminator value annotation if it is enum type.
Hi,
I provided repro for #5406 and this issue seems to be the only show-stopper for our project after migrating to RTM. Therefore I would like to know if it would be possible to manually fix new full-database migration and model snapshot to how it should look like after fixing this.
Curiously, specifying discriminant in .Designer.cs/ModelSnapshot.cs takes two forms:
b.HasDiscriminator<byte>("Type").HasValue(TicketBatchType.TicketBatch);
and
b.HasDiscriminator().HasValue(TicketBatchType.PrintBatch);
It seems that the first form is for base classes and second form for descendants.
Not the question is – what should be the correct form to use ? Is that settled yet ?
The snapshot (or any other part of migrations code) shouldn't have any references to your types in it, since you may change those over time. For example, if you decided to remove TicketBatchType from your model (which would be perfectly valid) then your snapshot would no longer compile.
For this reason, we typically convert enums to their underlying type - so the value should probably be stored as its byte value instead of the enum.
We haven't started work on fixing this yet, so I can't say exactly what the fix will ultimately be, but you could try swapping out the enum for the underlying value it represents.
BTW another workaround would be exclude the enum property from the EF model and have it be a wrapper over a byte property which is mapped to the database. The byte property could be private, so it doesn't show up for application code.
@AndriySvyryd With the advent of value converters, should values like HasDefaultValue() and HasDiscriminator().HasValue() be converted when the model is built?
@bricelam Yes, I just fixed it in e6894d01230abec664b7461aa76464edeaada3e0
Oh I see, we convert while generating the snapshot. 👍
Most helpful comment
The snapshot (or any other part of migrations code) shouldn't have any references to your types in it, since you may change those over time. For example, if you decided to remove
TicketBatchTypefrom your model (which would be perfectly valid) then your snapshot would no longer compile.For this reason, we typically convert enums to their underlying type - so the value should probably be stored as its
bytevalue instead of the enum.We haven't started work on fixing this yet, so I can't say exactly what the fix will ultimately be, but you could try swapping out the enum for the underlying value it represents.
BTW another workaround would be exclude the enum property from the EF model and have it be a wrapper over a
byteproperty which is mapped to the database. Thebyteproperty could be private, so it doesn't show up for application code.