CSLA 3.5 How to define a nullable int

CSLA 3.5 How to define a nullable int

Old forum URL: forums.lhotka.net/forums/t/5815.aspx


alef posted on Monday, November 17, 2008

When it is not a nullable int I'm using the following syntax for a property CityId:

 private static PropertyInfo<int> CityIdProperty = RegisterProperty<int>(typeof(Joiner), new PropertyInfo<int>("CityId"));

  public int CityId
   get { return GetProperty<int>(CityIdProperty); }
   set { SetProperty<int>(CityIdProperty, value); }

  #region Data Access - Fetch

    LoadProperty<int>(CityIdProperty, data.numCityId);

  #region Data Access - Insert

    data.numCityId = ReadProperty<int>(CityIdProperty);

  #region Data Access - Update

     data.numCityId = ReadProperty<int>(CityIdProperty);

 

When CityId can be nullable in the SQL database how do I define the property in CSLA 3.5?

Is the following OK?

  private static PropertyInfo<int?> CityIdProperty = RegisterProperty<int?>(typeof(Joiner), new PropertyInfo<int?>("CityId"));

  public int? CityId
   get { return GetProperty<int?>(CityIdProperty); }
   set { SetProperty<int?>(CityIdProperty, value); }

 #region Data Access - Fetch

    LoadProperty<int?>(CityIdProperty, data.numCityId);

  #region Data Access - Insert

    data.numCityId = ReadProperty<int?>(CityIdProperty);

  #region Data Access - Update

     data.numCityId = ReadProperty<int?>(CityIdProperty

 

Does somebody know how to define this in the xml document for the codesmith templates?

In the attribute NativeType int? doesn't exist.

skagen00 replied on Monday, November 17, 2008

We use nullable ints as you mention above.

One thing we did, though, for data access (we use stored procedures) is that null needs to be System.DbNull. So, we created some extension methods for nullable types.

        public static object DBValue(this int? value)
        {
            if (value.HasValue)
            {
                return value.Value;
            }
            else
            {
                return DBNull.Value;
            }
        }

This allows one do to something like this when adding parameters to the sproc (in the case below, it's a nulable datetime):

database.AddInParameter(command, _incorporatedDate.DataParameterName, DbType.DateTime, ReadProperty(_incorporatedDate).DBValue());

When fetching, one needs to check the datareader for DbNull, and if it's DbNull just don't load into it - leave it the default value of null (in the general case):


            if (!reader.IsDBNull(_incorporatedDate.DataColumnName))
            {
                LoadProperty<DateTime?>(_incorporatedDate, reader.GetDateTime(_incorporatedDate.DataColumnName));
            }

(DataColumnName and DataParameterName are just an extended properties of our own PropertyInfo objects, but you get the gist0.

So long story short, we use nullable propertyinfo objects without difficulty.

Chris

alef replied on Thursday, November 20, 2008

Very interesting.
Extension methods was something new for me, so I had to study a little bit.

So as you mentioned I created the following class:
  public static class MyExtensionMethods
  {
    public static object DBValue(this int? value)
    {
      if (value.HasValue)
      {
        return value.Value;
      }
      else
      {
        return DBNull.Value;
      }
    }
  }

In the method AddInsertParameters generated by CodeSmith I've changed  the following code
      if (CityId != null)
        cm.Parameters.AddWithValue("@CityId", ReadProperty<int?>(HoofdafdelingLIDProperty));
      else
        cm.Parameters.AddWithValue("@CityId", DBNull.Value);

to only 1 line as you suggested
cm.Parameters.AddWithValue("@CityId", ReadProperty<int?>(CityIdProperty).DBValue());
Thank you very much for this code reduction.

For Fetching I changed the code in the method FetchObject generated by CodeSmith from
    LoadProperty<int?>(CityIdProperty, dr.GetInt32("CityId"));
to
      if(!dr.IsDBNull("CityId"))
      {
        LoadProperty<int?>(CityIdProperty, dr.GetInt32("CityId"));
      }
We have to check for null with dr.IsDBNull because the method GetInt32 from SafeDataReader will convert null to 0 which is not what we want.

Can you provide the code for your own PropertyInfo objects and how to use them? This seems to me very interesting to get rid off the string literals @CityId , CityId




Copyright (c) Marimer LLC