c# - DbContext trying to save non-null fields as null -
i have 2 projects
storesku.data - depends on: microsoft.entityframeworkcore storesku.provider - depends on: storesku.data, microsoft.entityframeworkcore.sqlserver
i don't want tie storesku.data
particular provider, i've moved reposonsibility storesku.provider
. i'm creating model , options within storesku.provider
, passing options dbcontext
using following code:
var optionsbuilder = new dbcontextoptionsbuilder(); optionsbuilder.usesqlserver(connectionstring); var conventions = new conventionset(); var modelbuilder = new modelbuilder(conventions); modelbuilder.entity<storeskuupdaterequest>().haskey(request => request.id); modelbuilder.entity<storeskuupdaterequest>().property(request => request.id).usesqlserveridentitycolumn(); modelbuilder.entity<storeskuupdaterequest>().property(request => request.storenumber).valuegeneratednever(); modelbuilder.entity<storeskuupdaterequest>().property(request => request.businessdate).valuegeneratednever(); modelbuilder.entity<storeskuupdaterequest>().property(request => request.timestamp).valuegeneratednever(); modelbuilder.entity<storeskuupdaterequest>().hasmany(request => request.requestedupdates).withone(update => update.updaterequest); modelbuilder.entity<storeskuupdaterequest>().hasmany(request => request.relatedupdates).withone(relatedupdate => relatedupdate.updaterequest); modelbuilder.entity<storeskuupdaterequest>().forsqlservertotable("storeskuupdaterequest"); modelbuilder.entity<storeskuavailabilityupdate>().hasone(update => update.updaterequest).withmany(request => request.requestedupdates); modelbuilder.entity<storeskuavailabilityupdate>().hasmany(update => update.relatedupdates).withone(relatedupdate => relatedupdate.requestedupdate); modelbuilder.entity<storeskuavailabilityupdate>().forsqlservertotable("requestedstoreskuupdate"); modelbuilder.entity<relatedstoreskuupdate>().hasone(relatedupdate => relatedupdate.requestedupdate).withmany(update => update.relatedupdates); modelbuilder.entity<relatedstoreskuupdate>().hasone(relatedupdate => relatedupdate.updaterequest).withmany(request => request.relatedupdates); modelbuilder.entity<relatedstoreskuupdate>().forsqlservertotable("relatedstoreskuupdate"); optionsbuilder.usemodel(modelbuilder.model); dbcontextoptions options = optionsbuilder.options;
as can see, it's pretty verbose. whether need of these calls different question. question focuses more along these lines:
modelbuilder.entity<storeskuupdaterequest>().property(request => request.storenumber).valuegeneratednever(); modelbuilder.entity<storeskuupdaterequest>().property(request => request.businessdate).valuegeneratednever(); modelbuilder.entity<storeskuupdaterequest>().property(request => request.timestamp).valuegeneratednever();
the error i've run if don't have these lines, following errors:
cannot insert value null column 'storenumber', table 'dbo.storeskuupdaterequest'; column not allow nulls. insert fails. statement has been terminated. cannot insert value null column 'businessdate', table 'dbo.storeskuupdaterequest'; column not allow nulls. insert fails. statement has been terminated. cannot insert value null column 'timestamp', table 'dbo.storeskuupdaterequest'; column not allow nulls. insert fails. statement has been terminated.
the schema table is
create table [dbo].[storeskuupdaterequest]( [id] [bigint] identity(1,1) not null, [storenumber] [int] not null, [businessdate] [date] not null, [timestamp] [datetime] not null)
and model
public sealed class storeskuupdaterequest { [required] public long id { get; set; } [required] public int storenumber { get; set; } [required] public datetime businessdate { get; set; } [required] public datetime timestamp { get; set; } }
and calling code:
using (context) { var request = new storeskuupdaterequest { storenumber = 12345, businessdate = datetime.utcnow, timestamp = datetime.utcnow }; context.storeskuavailabilityupdaterequests.add(request); context.savechanges(); }
and sql command being generated is
begin transaction set nocount on; insert [storeskuupdaterequest] default values; select [id] [storeskuupdaterequest] @@rowcount = 1 , [id] = scope_identity(); rollback transaction
why have specify valuegeneratednever();
each of these properties? why efcore trying save them null
?
based on comment ivan stoev in original post, stumbled upon little bit https://github.com/aspnet/entityframework/issues/3529
discussed in triage , decided should have modelbuilder factories folks don't need worry conventions etc. (especially since conventions 'internal' first release).
folks can create 1 (note static create() method on factory rather default ctor factory since having default ctor doesn't play di):
var builder = sqlservermodelbuilderfactory.create()
alternatively, if want it's services di we'll register 1 can resolve... same logger, etc. registered in di (plus if have overridden type mapper etc. services).
sp.addentityframework() .addsqlcompact() .addnpgsql() .addsqlserver()
;
var builder = sp.getservice<isqlservermodelbuilderfactory>().create();
i wasn't able find sqlservermodelbuilderfactory
class, led me investigate if there sqlserverconventionsetbuilder
; there was.
so changing from
var conventions = new conventionset();
to
var conventions = sqlserverconventionsetbuilder.build();
fixed me right up.
Comments
Post a Comment