.SetNewFieldValue

Posts   
 
    
jeffreygg
User
Posts: 805
Joined: 26-Oct-2003
# Posted on: 14-Oct-2004 01:03:53   

It appears that the value set by .SetNewFieldValue is not being overwritten by the direct calls to the property later on. If I set a field's value to "nothing" via the .SetNewFieldValue method, then later try to write a value directly to field via the property, the new value doesn't seem to get set.

Any thoughts?

Jeff...

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 14-Oct-2004 09:54:48   

Hmm. I think this is a bug. There was an issue with this when you had set the field to null/Nothing, and set it again later on to a value, you got an exception, which was fixed during the beta, but this fix apparently introduced this bug. (i.e.: it skips setting the value, if the field is already null/Nothing, unless the entity is new.

Will work on a fix. simple_smile

(edit): fix is now available in the hotfix for the runtimelibs

Frans Bouma | Lead developer LLBLGen Pro
jeffreygg
User
Posts: 805
Joined: 26-Oct-2003
# Posted on: 14-Oct-2004 20:07:01   

Thanks, Frans.

Jeff...

BSAPD avatar
BSAPD
User
Posts: 42
Joined: 02-Jul-2004
# Posted on: 16-Nov-2004 03:21:54   

I think I am having a similar issue with the latest release installed. I am setting a DateTime property on an entity to DateTime.MinValue at the beginning of a request and then later during the request (Before Saving) I am validating the values. In my validation DateTime.MinValue is the equivalent of a null, so I am using the SetNewFieldValue method to set the value to null.

if(_Contract.RequirementsReceived == DateTime.MinValue) { _Contract.SetNewFieldValue("RequirementsReceived", null); _Errors.Add(new RequiredFieldError("Requirements Received")); }

Since the field cannot be null I an displaying a validation error to the user and NOT saving the data. (NOTE: the entity is persisted to the session between requests) Now, when a valid date is entered on the form I again try to set the value using the property and the date does not get set. The SetNewFieldValue method will now always return false.

I am having the same issue with some int properties but I haven't had a chance to step through them yet.

Here is the function that converts the TextBox value to a date:

/// <summary> /// Use this function to convert an object to a date. /// </summary> /// <param name="valueToConvert"></param> /// <returns>Date or 1/1/1.</returns> public static DateTime ConvertToDate(object valueToConvert) { try { if(valueToConvert.GetType() == typeof(string)) { if(((string)valueToConvert).IndexOf("_") > -1) { return DateTime.MinValue; } } return Convert.ToDateTime(valueToConvert); } catch { return DateTime.MinValue; } }

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 16-Nov-2004 11:08:37   

This is the code which tests if the value should be set:


// field value has to be updated in the following situations:
// - when the entity is new
// - when the entity is not new and:
//      - the field's DbValue is null
//      - the field's DbValue is not null and the field's CurrentValue is different than the new value and not null
//      - the field's CurrentValue is null
if(_isNew ||
    (!_isNew && (
        (fieldToSet.DbValue==null) ||
        (fieldToSet.CurrentValue==null) ||
        ((fieldToSet.DbValue!=null) && (fieldToSet.CurrentValue!=null) && !fieldToSet.CurrentValue.Equals(value)))))
{
//... set field

As CurrentValue == null, it falls through. So I'm a bit confused what might be the case in your situation. So when you enter a valid date after the field is set to null, the field does not get updated?

Frans Bouma | Lead developer LLBLGen Pro
BSAPD avatar
BSAPD
User
Posts: 42
Joined: 02-Jul-2004
# Posted on: 16-Nov-2004 16:30:41   

I agree, it looks like it should set the value. I have been fighting with this for two days now. I hope I don't need to change how I am validating as this would be a huge effort at this point. I stepped through my process and captured the state of the EntityField2, here are the results...

First time after retrieved form the DB: ?this.Fields[12] {SD.LLBLGen.Pro.ORMSupportClasses.EntityField2} System.Object: {SD.LLBLGen.Pro.ORMSupportClasses.EntityField2} _aggregateFunctionToApply: None _alias: "RequirementsReceived" _containingObjectName: "ContractEntity" _currentValue: {8/26/2003} _dataType: {"System.DateTime"} _dbValue: {8/26/2003} _expressionToApply: <undefined value> _fieldIndex: 12 _isChanged: false _isForeignKey: false _isNull: false _isPrimaryKey: false _maxLength: 0 _name: "RequirementsReceived" _objectAlias: "" _originalValue: <undefined value> _precision: 23 _scale: 3 AggregateFunctionToApply: None Alias: "RequirementsReceived" ContainingObjectName: "ContractEntity" CurrentValue: {8/26/2003} DataType: {"System.DateTime"} DbValue: {8/26/2003} ExpressionToApply: <undefined value> FieldIndex: 12 IsChanged: false IsForeignKey: false IsNull: false IsPrimaryKey: false MaxLength: 0 Name: "RequirementsReceived" ObjectAlias: "" OriginalValue: <undefined value> Precision: 23 Scale: 3

Now set the property value to DateTime.MinVal (Value is actually set): ?this.Fields[12] {SD.LLBLGen.Pro.ORMSupportClasses.EntityField2} System.Object: {SD.LLBLGen.Pro.ORMSupportClasses.EntityField2} _aggregateFunctionToApply: None _alias: "RequirementsReceived" _containingObjectName: "ContractEntity" _currentValue: {1/1/1} _dataType: {"System.DateTime"} _dbValue: {8/26/2003} _expressionToApply: <undefined value> _fieldIndex: 12 _isChanged: true _isForeignKey: false _isNull: false _isPrimaryKey: false _maxLength: 0 _name: "RequirementsReceived" _objectAlias: "" _originalValue: {8/26/2003} _precision: 23 _scale: 3 AggregateFunctionToApply: None Alias: "RequirementsReceived" ContainingObjectName: "ContractEntity" CurrentValue: {1/1/1} DataType: {"System.DateTime"} DbValue: {8/26/2003} ExpressionToApply: <undefined value> FieldIndex: 12 IsChanged: true IsForeignKey: false IsNull: false IsPrimaryKey: false MaxLength: 0 Name: "RequirementsReceived" ObjectAlias: "" OriginalValue: {8/26/2003} Precision: 23 Scale: 3

Now after validation use SetNewFieldValue to set to null: ?_Contract.Fields[12] {SD.LLBLGen.Pro.ORMSupportClasses.EntityField2} System.Object: {SD.LLBLGen.Pro.ORMSupportClasses.EntityField2} _aggregateFunctionToApply: None _alias: "RequirementsReceived" _containingObjectName: "ContractEntity" _currentValue: <undefined value> _dataType: {"System.DateTime"} _dbValue: {8/26/2003} _expressionToApply: <undefined value> _fieldIndex: 12 _isChanged: true _isForeignKey: false _isNull: false _isPrimaryKey: false _maxLength: 0 _name: "RequirementsReceived" _objectAlias: "" _originalValue: {1/1/1} _precision: 23 _scale: 3 AggregateFunctionToApply: None Alias: "RequirementsReceived" ContainingObjectName: "ContractEntity" CurrentValue: <undefined value> DataType: {"System.DateTime"} DbValue: {8/26/2003} ExpressionToApply: <undefined value> FieldIndex: 12 IsChanged: true IsForeignKey: false IsNull: false IsPrimaryKey: false MaxLength: 0 Name: "RequirementsReceived" ObjectAlias: "" OriginalValue: {1/1/1} Precision: 23 Scale: 3

Now try to set property to DateTime.Now() and it wont work: ?this.Fields[12] {SD.LLBLGen.Pro.ORMSupportClasses.EntityField2} System.Object: {SD.LLBLGen.Pro.ORMSupportClasses.EntityField2} _aggregateFunctionToApply: None _alias: "RequirementsReceived" _containingObjectName: "ContractEntity" _currentValue: <undefined value> _dataType: {"System.DateTime"} _dbValue: {8/26/2003} _expressionToApply: <undefined value> _fieldIndex: 12 _isChanged: true _isForeignKey: false _isNull: false _isPrimaryKey: false _maxLength: 0 _name: "RequirementsReceived" _objectAlias: "" _originalValue: {1/1/1} _precision: 23 _scale: 3 AggregateFunctionToApply: None Alias: "RequirementsReceived" ContainingObjectName: "ContractEntity" CurrentValue: <undefined value> DataType: {"System.DateTime"} DbValue: {8/26/2003} ExpressionToApply: <undefined value> FieldIndex: 12 IsChanged: true IsForeignKey: false IsNull: false IsPrimaryKey: false MaxLength: 0 Name: "RequirementsReceived" ObjectAlias: "" OriginalValue: {1/1/1} Precision: 23 Scale: 3

The version of the ORM DLL is: 1.0.2004.1

(EDIT) I just looked at some other fields and I am getting the same issue (float, int, & varchar).

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 16-Nov-2004 17:11:51   

So with this state:


Now after validation use SetNewFieldValue to set to null:
?_Contract.Fields[12]
{SD.LLBLGen.Pro.ORMSupportClasses.EntityField2}
System.Object: {SD.LLBLGen.Pro.ORMSupportClasses.EntityField2}
_aggregateFunctionToApply: None
_alias: "RequirementsReceived"
_containingObjectName: "ContractEntity"
_currentValue: <undefined value>
_dataType: {"System.DateTime"}
_dbValue: {8/26/2003}
_expressionToApply: <undefined value>
_fieldIndex: 12
_isChanged: true
_isForeignKey: false
_isNull: false
_isPrimaryKey: false
_maxLength: 0
_name: "RequirementsReceived"
_objectAlias: ""
_originalValue: {1/1/1}
_precision: 23
_scale: 3
AggregateFunctionToApply: None
Alias: "RequirementsReceived"
ContainingObjectName: "ContractEntity"
CurrentValue: <undefined value>
DataType: {"System.DateTime"}
DbValue: {8/26/2003}
ExpressionToApply: <undefined value>
FieldIndex: 12
IsChanged: true
IsForeignKey: false
IsNull: false
IsPrimaryKey: false
MaxLength: 0
Name: "RequirementsReceived"
ObjectAlias: ""
OriginalValue: {1/1/1}
Precision: 23
Scale: 3

the value wasn't set?

Some questions to make my debugging survey a bit shorter: - is the entity new? - adapter or selfservicing? that was a dumb question simple_smile - is there code in the validation class for this entity? - when you set teh field to DateTime.Now(), is the field still bound to the grid? (as IEditableObject methods can get in the way)

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 16-Nov-2004 17:31:57   

I made this small test, does this represent the situation in your routine?

[Test] public void ValueSetTest() { OrderEntity order = new OrderEntity(); order.OrderDate = DateTime.MinValue; Assert.IsTrue(order.IsDirty); Assert.IsTrue(order.Fields[(int)OrderFieldIndex.OrderDate].IsChanged); Assert.AreEqual(DateTime.MinValue, order.Fields[(int)OrderFieldIndex.OrderDate].CurrentValue);

Assert.IsTrue(order.SetNewFieldValue((int)OrderFieldIndex.OrderDate, null));
Assert.IsNull(order.Fields[(int)OrderFieldIndex.OrderDate].CurrentValue);

DateTime newDate = DateTime.Now;
order.OrderDate = newDate;

Assert.AreEqual(newDate, order.Fields[(int)OrderFieldIndex.OrderDate].CurrentValue);

}

passes.

Frans Bouma | Lead developer LLBLGen Pro
BSAPD avatar
BSAPD
User
Posts: 42
Joined: 02-Jul-2004
# Posted on: 16-Nov-2004 17:46:08   

Otis wrote:

So with this state: the value wasn't set?

Some questions to make my debugging survey a bit shorter: - is the entity new? - adapter or selfservicing? that was a dumb question simple_smile - is there code in the validation class for this entity? - when you set the field to DateTime.Now(), is the field still bound to the grid? (as IEditableObject methods can get in the way)

No, the value does not get set. Its very puzzling. confused

Answers:

-the entity is not new -there is no code in the validation class -this field is not bound to anything

Other things that may help:

-ASP.NET/C# -Entity is stored in session between postbacks -Entity is exposed to the code behind class via a screen controller class (just as a public property) -SQL Server 2000 -Adapter scenario (Full / Safe) Vs.Net 2003 (Version: 1.0.2004.1.061404) -C# template set for SqlServer (1.0.2004.1) (Version: 1.0.2004.1.102604)

If there is anything else I can do please let me know.

BSAPD avatar
BSAPD
User
Posts: 42
Joined: 02-Jul-2004
# Posted on: 16-Nov-2004 17:50:42   

Otis wrote:

I made this small test, does this represent the situation in your routine?

[Test] public void ValueSetTest() { OrderEntity order = new OrderEntity(); order.OrderDate = DateTime.MinValue; Assert.IsTrue(order.IsDirty); Assert.IsTrue(order.Fields[(int)OrderFieldIndex.OrderDate].IsChanged); Assert.AreEqual(DateTime.MinValue, order.Fields[(int)OrderFieldIndex.OrderDate].CurrentValue);

Assert.IsTrue(order.SetNewFieldValue((int)OrderFieldIndex.OrderDate, null));
Assert.IsNull(order.Fields[(int)OrderFieldIndex.OrderDate].CurrentValue);

DateTime newDate = DateTime.Now;
order.OrderDate = newDate;

Assert.AreEqual(newDate, order.Fields[(int)OrderFieldIndex.OrderDate].CurrentValue);

}

passes.

Its not a new entity...

on the last test

order.OrderDate = newDate;

if I step into the generated code it calls SetNewFieldValue and that returns false.

BSAPD avatar
BSAPD
User
Posts: 42
Joined: 02-Jul-2004
# Posted on: 16-Nov-2004 21:30:41   

This is some output into my immediate window:

?!this.IsNew && this.Fields[12].CurrentValue == null true

As you can see the result is true, based on the if statement you posted it should set the value. When the code executes:

if(base.SetNewFieldValue((int)ContractFieldIndex.RequirementsReceived, value)) { // value set. Set related entities to null (if any), related via this field

// flag as changed OnRequirementsReceivedChanged(); }

it does not set the field.

I also ran a test:

[Test] public void ValueSetTest() { IDataAccessAdapter adapter = HOO.LARS.BLL.HelperClasses.DataHelper.GetDataAdapter(); ContractEntity contract = new ContractEntity(1); adapter.FetchEntity(contract);

contract.RequirementsReceived = DateTime.MinValue;

Assert.IsTrue(contract.IsDirty); Assert.IsTrue(contract.Fields[(int)ContractFieldIndex.RequirementsReceived].IsChanged); Assert.AreEqual(DateTime.MinValue, contract.Fields[(int)ContractFieldIndex.RequirementsReceived].CurrentValue);

Assert.IsTrue(contract.SetNewFieldValue((int)ContractFieldIndex.RequirementsReceived, null)); Assert.IsNull(contract.Fields[(int)ContractFieldIndex.RequirementsReceived].CurrentValue);

DateTime newDate = DateTime.Now; contract.RequirementsReceived = newDate;

Assert.AreEqual(newDate, contract.Fields[(int)ContractFieldIndex.RequirementsReceived].CurrentValue); }

and the test passes, but that doesn't help me. Is there some chance that my dll's are messed up? I am really stuck here. Please Help!!!

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 16-Nov-2004 21:50:41   

Hmm. Some basic checks:

  • open command prompt, do: vsvars32.bat and gacutil /ldl you shouldn't see a list of dll's. If you see a list, do gacutil /cdl
  • remove the ormsupportclasses.dll from the gac if you have added it there (manually or through an installer)

  • check your complete project that the references are set correctly. Rebuild everything and as you're working on a webapplication, be absolutely sure the bin folder contains the latest dlls.

If that doesn't work, grab the sourcecode from the website and build your own debug build of the runtime libs and step into SetNewFieldValue() to see what really happens... (be sure to remove the strong key name from the assemblyinfo.cs file)

Frans Bouma | Lead developer LLBLGen Pro
BSAPD avatar
BSAPD
User
Posts: 42
Joined: 02-Jul-2004
# Posted on: 17-Nov-2004 01:20:32   

Hello Otis,

Well, I downloaded the source like you suggested and compiled a debug version. I stepped through all the code and everything worked as expected. I am just going to compile a release version of the source and use that (unless you see an issue with that). I have no explanation for what happened. The only thing I can think of is VS would not update the references.

Thanks for you're help.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 17-Nov-2004 09:42:14   

Another customer had also issues with release builds which worked but the shipped versions didn't. It turned out that the GAC contained an ORMSupportclasses version.

In either case, because it's a webapp, copy the dll's manually to the bin folder to make sure the right dll's are in the webapp's folder. (and check if there are runtimelib dll's in the gac, they shouldn't be in the gac)

Frans Bouma | Lead developer LLBLGen Pro