My model contains an entity Order with a non-nullable property Amount of type decimal:
cf:entity name="Order">
<cf:property name="Id" />
<cf:property name="Amount" typeName="decimal" defaultValue="0" nullable="false" />
</cf:entity>
I can not save an instance of this entity with the value 0 for the property Amount, because when calling "Order.Save()" I get the error "Procedure or function 'Order_Save' expects parameter '@Amount', which was not supplied." from SQL-Server.
Everything goes fine if I give the parameter the default value 0 in the stored procedure: ALTER PROCEDURE [dbo].[Order_Save] ( @Amount [decimal] (28, 13) = 0, ...
How can I instruct CodeFluent to generate a stored procedure with the default value 0 for the Amount parameter? Or do you know another solution?
Kind regards
You have to set usePersistenceDefaultValue="false"
:
<cf:entity name="Order">
<cf:property name="Id" />
<cf:property name="Amount" typeName="decimal" nullable="false" usePersistenceDefaultValue="false" />
</cf:entity>
https://www.softfluent.com/documentation/Properties_DefaultValues.html
The root cause of this is related to Object-relational impedance mismatch that CodeFluent Entities tries to fix.
- On the database side you can define a nullable column for an integral type (this is not the case here, but the implications are the same)
- On the .NET side, you define an integral type that cannot be null.
To fix the null impedance mismatch between those worlds, CodeFluent Entities defines a 'default value' concept on the .NET side. This follows the Sentinel value pattern.
The .NET side 'default value' for this property will be the .NET value that will be equivalent to null on the database side. By default, this value is 0 for a number (and -1 for an identity number).
So, when you send a 0 to the database, it's equivalent to sending a null. In the other way, if you store a null in the database, you'll get a 0 in the .NET property.
Note that unlike most ORMs - CodeFluent Entities is not an ORM but it does contain Object to Relational mapping technology - you will not get an error or an exception because you map nullable column to non nullable .NET types, it'll work like a charm, thanks to this default value concept. It's very practical because in the end, it allows us to map non nullable .NET types to nullable database columns. You don't have to use int?
to declare a nullable int column (but you can if you want, CodeFluent Entities supports it).
In your case, since the column is not nullable, you logically get an error if you send a .NET 0.
So, you can choose to not use the 'default value' concept (like in meziantou's answer), or also you can define another default value (like defaultValue="-1" for example, or -2 for an identity column), but you'll still get an error if you send this new default value from .NET.
来源:https://stackoverflow.com/questions/35781816/can-not-save-an-entity-with-the-value-0-for-a-non-nullable-numeric-property