This project has moved. For the latest updates, please go here.

Nullables not correct for string

Developer
Nov 19, 2010 at 5:30 PM

Tiago,

If a string is nullable then there is a problem with the definition:
        public static PropertyInfo<string> Name2Property = RegisterProperty<string>(p => p.Name2, "Name2");
should be:
        public static PropertyInfo<string> Name2Property = RegisterProperty<string>(p => p.Name2, "Name2", null);

and the load:
            LoadProperty(Name2Property, dr.GetString("Name2"));
should be:
            LoadProperty(Name2Property, dr.GetValue("Name2"));

The code for the parameter IS already correct:
            cmd.Parameters.AddWithValue("@Amount2", ReadProperty(Amount2Property) == null ? (object) DBNull.Value : ReadProperty(Amount2Property).Value).DbType = DbType.Decimal;

Bill

Coordinator
Nov 19, 2010 at 10:26 PM
Blarm wrote:

        public static PropertyInfo<string> Name2Property = RegisterProperty<string>(p => p.Name2, "Name2", null);

Hi Bill,

The "null" at the end of the assignement means the default value is null.

There are two ways to assing a default vale to PropertyInfo. One of them is the one in your sample. The other is on the DataPortal_Create/Create_Child. When writing the C# templates I favoured the later as the former only allow static values. To illustrate what I'm saying, try to enter _lastID in the default value of a PK property. You get

#region Static Fields

private static int _lastID;

#endregion

and on DataPortal_Create() you get

LoadProperty(FolderIDPropertySystem.Threading.Interlocked.Decrement(ref _lastID));

This doesn't work as it should if assigned on the PropertyInfo declaration as it is assigned statically and always returns the same value.

As you might know from reading Rocky's posts on the forum and on several release notes, over the years he succeeded to reduce the amount of code you have to type and that is a major concern for him. Assigning the default on PropertyInfo declaration has a clear purpose of avoiding the need for the DataPortal_Create method. It's a good solution if you manage to set all your defaults this way. But it only answers the requisite for fixed value defaults. If you need default values that aren't fixed i.e. that change according to whatever conditions or that are loaded from the database you still need to use DataPortal_Create method.

Since we are code generating, there is no need to use these techniques that were designed to reduce hand typing. If these techniques have some disadvantages and you can avoid them altogether...

One might argue that CslaGenFork should allow the option of using one or the other way of specifyng defaults. And "one" might be right. It should be done at the project or object level, as it would be too confusing to set default values both ways. You would have two places to look for the default value. If you need one single default specified in DataPortal_Create, all of them must also be there. For me it isn't clear enough we need any alternative to the DataPortal_Create way.

Back to the point, you can always set the default to null and it will show up in DataPortal_Create. So this isn't an issue. The REAL POINT is whether or not CslaGenFork templates should presume that a string type property marked as nullable should have a NULL value by default (unless you explictly say otherwise). This is a good and valid pont. This default will be set in DataPortal_Create

Using GetValue instead of GetString is also a valid point.

This will be promoted to Work Item

Coordinator
Nov 19, 2010 at 10:30 PM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.
Coordinator
Nov 19, 2010 at 10:30 PM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.
Coordinator
Nov 19, 2010 at 10:31 PM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.
Coordinator
Nov 21, 2010 at 12:53 AM

Sorry about the triplicated copies made to work items (very slow connection and very impatient user). I reused two of those.

Developer
Nov 21, 2010 at 3:00 PM

Hi Tiago,

My thinking behind setting the default to null on the definition was that all other types are set correctly on definition.

If a type is decimal it gets set to 0 and if decimal? is gets set to null.

A string is different in that it allows null and there is not a string? type, so RegisterProperty sets it to String.Empty , but I thought it would be more complete to have the default value set at definition time. That way if you are not generating the DataPortal_Create() then all the properties are set correctly at definition.

I agree that if you are specifiying default values in CSLAGen then the best place to generate the code to set them is in DataPortal_Create() and if you do not generate the Data_Portal then it is up to you to code the setting of default values yourself.

Bill

Coordinator
Nov 21, 2010 at 6:39 PM
Blarm wrote:

I agree that if you are specifiying default values in CSLAGen then the best place to generate the code to set them is in DataPortal_Create() and if you do not generate the Data_Portal then it is up to you to code the setting of default values yourself.

 Hi Bill,

I don't agree with the "it's up to you to code..." when we are talking about code generator. The principle I try to follow is

You shouldn't have to edit the generated code.

You might have to add your own methods to extend the generate ones (like when you write the other part of a partial method) or instead of not generated ones (like when you do not Generate Insert() Method). That's the way to allow painless code re-generation. The point here is... well there is no point really. It's solved: nullable strings will generate a null assignement in DataPortal_Create.

Unless you have to DataPortal_Create... That's possible if you set CreateOptions.DataPortal to false. If you do, no DataPortal_Create is generated. On managed properties (I mean those that use PropertyInfo) you could try to assign defaults. Then you could say: "if the default isn't fixed value and you don't get the expected results, it's your problem".

Moving this requisite to a work item:

If an object has no criteria with CreateOptions.DataPortal set to true (no DataPortal_Create is generated and BusinessRules.CheckRules() won't run) the default value of all properties will be assigned on the PropertyInfo declaration for properties that are declared that way.

Coordinator
Nov 21, 2010 at 6:40 PM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.