zero values turned into null in queries

Posts   
 
    
dvdstelt
User
Posts: 22
Joined: 06-Dec-2005
# Posted on: 11-Apr-2006 15:10:29   

Hi there,

When I create a new entity and fill some of its values with 0 (or zeros) using databinded input controls, it doesn't save those values. Any idea how this is happening? The fields in the database are marked as not-null, so my query throws an exception in the database.

Thanks in advance, Dennis

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 11-Apr-2006 15:27:23   

Default values for numeric dataTypes in .Net are Zeros. And when you set a Field which has (by default) a value of Zero to a value of Zero, it doesn't feel to be changed, So nothing will be set in the Database coz the field seem to be Unchanged.

Options: 1- Set the IsCahanged property to true. 2- Use SetNewFieldValue() to set it to Zero. 3- Use a default value (Zero) in the database for those fields, so when they are not been set to something, they will take the value of Zero rather than Null.

I always use the last option.

dvdstelt
User
Posts: 22
Joined: 06-Dec-2005
# Posted on: 11-Apr-2006 15:40:11   

Walaa wrote:

1- Set the IsCahanged property to true. 2- Use SetNewFieldValue() to set it to Zero. 3- Use a default value (Zero) in the database for those fields, so when they are not been set to something, they will take the value of Zero rather than Null.

I always use the last option.

1 isn't an option, according to Frans. I almost had a fight with him over that one! wink It was on a different topic though, about the deletion flag. 2 works, but sucks 3 works and is probably the best solution available

But still, it's kind of a sucky solution.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39928
Joined: 17-Aug-2003
# Posted on: 11-Apr-2006 15:55:08   

[Test]
public void SettingValuesOnNewEntityTest()
{
    OrderEntity order = new OrderEntity();
    order.EmployeeId = 0;
    Assert.IsTrue(order.IsDirty);
    Assert.IsTrue(order.Fields[(int)OrderFieldIndex.EmployeeId].IsChanged);
}

EmployeeId is an int.

I'm not sure what you're doing, Dennis, but setting a field's value to the default value on a new entity simply works and makes the entity's field changed and will thus be saved.

Databinding a textbox to EmployeeId will thus also work, when I set it to 0.

How exactly are you setting the values ?

Frans Bouma | Lead developer LLBLGen Pro
dvdstelt
User
Posts: 22
Joined: 06-Dec-2005
# Posted on: 11-Apr-2006 16:28:46   

Otis wrote:

EmployeeId is an int.

I'm not sure what you're doing, Dennis, but setting a field's value to the default value on a new entity simply works and makes the entity's field changed and will thus be saved.

Databinding a textbox to EmployeeId will thus also work, when I set it to 0.

How exactly are you setting the values ?

Okay, what's happening is about this. I'm renaming the entities to something hopefully more understandable.

We have a table called "Order" and a table "OrderLines" in a 1:n relationship. On our WinForm, we're showing Order on the form and OrderLines in a list. We have a button to add a new orderline. When pressed, we instantiate a new orderline and do _order.OrderLines.Add(myOrderline);

Than myOrderline shows up in the listbox that shows all orderlines, belonging to this order. We manually select the orderline from the listbox. Than the changed event of the listbox is executed.

What happens next is that we set the SelectedItem from the listbox to a databindingsource. The selected orderline immediatly shows up in some extra textboxes. SURPRISE! All int fields have value 0!!!

Now we do nothing, and hit save! When looking into the order.orderlines, we see that one object IsNew and IsDirty. However, the properties with value 0 are NOT saved. And because those columns are "Allow Nulls = false" we get a nice little exception on the winform simple_smile

When we're looking at the SQL Profiler it's also noticed that the columns with those 0 values aren't included in the update insert query.

ps. In table OrderLines we have 4 float columns and two foreign key columns. The foreign keys are included in the insert into statement.

edit : changed update into insert, mistype

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39928
Joined: 17-Aug-2003
# Posted on: 11-Apr-2006 17:22:11   

The values you see are the default values though they're not set in the entity, because you haven't set anything. An int property has to return an int, it can't return NULL or DBNull, or nothing or whatever, it has to return a value, hence the value 0.

Now, if you WANT TO have nulls in the db (you don't, but say you want to), you don't set these fields, call save and you get NULL values for these fields, as they're not changed.

If you DON'T want to have NULL values for these fields, set them to an appropriate value.

The Fields aren't marked as changed if you don't set them to a value. This is done to prevent 'phantom inserts' where you don't change anything but still get data inserted into the db.

Frans Bouma | Lead developer LLBLGen Pro