StrataFrame Forum

Exception with Extended Properties

http://forum.strataframe.net/Topic15238.aspx

By Ertan Deniz - 3/28/2008

I've an extended property called ClientAccountName. When I fill the Business Object which based on table mt_pch_companies, An exception was thrown. What should I do ?

Exception :

Column 'ClientAccountName' does not belong to table mt_pch_companies.

By Ertan Deniz - 3/28/2008

What about the columns belong to the table, I 've written an sql to select some of the fields but I'm getting an argument exception :

Column 'code' does not belong to table mt_pch_companies.

Because I couldn't select this column. What is the way of managing column and object properties with these conditions ?

By Trent L. Taylor - 3/29/2008

The only way that you would get an error is if:

  1. The custom property is an actual field in the table that is expected when updating in which case you would want to add the field to the ExcludeOnUpdates property.
  2. You are evaluating the field (referencing the field) when you have not pulled back the field that is used by the custom field
  3. Calling the MyBo.Item property to retrieve the vaue from within that item which would cause a recursive error in which case you should be using MyBo.CurrentRow.Item("MyField")
By Ertan Deniz - 5/16/2008

I had problems with extended columns. At this time, The exception that I have got was related to binding.

I have not bound the extended column (A) to the grid. But When navigating in the grid, The exception "Column A does not belong to table X".

There must be an easy way to control and manage the extended properties and properties that are not used with current state of the object. This was the reason why they were not selected. Otherwise, All the properties and extended properties have to be selected in each query. It is not optimal when we have many relations (extended properties from other objects.) to do so.

Note : Extended properties are used to binding purposes.

By Trent L. Taylor - 5/16/2008

Binding requires that you provide a type descriptor...I recommend doing a search on GetCustomBindablePropertyDescriptors....there should be a ton of posts on this.  Bottom line is that if you attempt to bind to a column that does not have a descriptor, you will get an error.
By Ertan Deniz - 5/16/2008

protected override FieldPropertyDescriptor[] GetCustomBindablePropertyDescriptors()

{

return new FieldPropertyDescriptor[]

{

new ReflectionPropertyDescriptor("ClientAccountName", typeof(Companies)),

new ReflectionPropertyDescriptor("GroupName", typeof(Companies))

};

}

I 've written the code necessary for the extended properties. The problem is that When we does not select any property (predefined or exteneded) with our query. Business object's table contains only selected columns. Business object is bound to a grid through BBS. Business object contains all the property definitions but table contains only selected ones. This is the central of the problem. After selecting a record on the grid, When we press a button, an exception is thrown. This exception is catched by the InvalidRowException event of the Devexpress Grid. Internally, there is an access to the properties of the business object that is not selected to be shown on the grid. We don't select them because there is no need to show.

This is the my case in detail.

By Trent L. Taylor - 5/19/2008

Well, I see your point, and this is actually by design.  You are wanting to perform a query, and then the internal ADO.NET table to automatically have all of the columns for the table.  This is not how the logic of a BO works.  It expects those columns to be included within the query or to be defined.  In our medical software, we actually have a shared method that ensures that columns and their default values exist in the case that we attempt to reference it, etc.  It looks something like this:

    ''' <summary>
    ''' Ensures that the column specified exists within the table.
    ''' </summary>
    ''' <param name="table"></param>
    ''' <param name="columnName"></param>
    ''' <param name="columnType"></param>
    ''' <param name="defaultValue"></param>
    ''' <remarks></remarks>
    Public Shared Sub EnsureColumnExists(ByVal table As DataTable, ByVal columnName As String, ByVal columnType As System.Type, ByVal defaultValue As Object)
        '-- Establish Locals
        Dim col As DataColumn
        Dim columnFound As Boolean = False

        '-- Cycle through all of the columns so we can test on a case-insensitive basis
        For Each col In table.Columns
            '-- Check to see if the column name matches
            columnFound = col.ColumnName.Equals(columnName, StringComparison.OrdinalIgnoreCase)

            '-- If the column was found, exit
            If columnFound Then Exit For
        Next

        '-- See if there is any reason to continue
        If columnFound Then Exit Sub

        '-- If we make it to this point, then we have a hit
        col = New DataColumn(columnName, columnType)
        col.DefaultValue = defaultValue

        '-- Add the column to the table
        table.Columns.Add(col)
    End Sub

By Ertan Deniz - 5/19/2008

Thanks.
By Ertan Deniz - 5/19/2008

Where is the place of this method called in the code ? You said when referencing a column.

Should you give me an explanation ? 

By Ertan Deniz - 5/21/2008

Any comment ? I 'm trying to find easy way ? (Shared) Central point to write the code. (EnsureColumnsExist)
By Trent L. Taylor - 5/21/2008

Any comment ? I 'm trying to find easy way ? (Shared) Central point to write the code. (EnsureColumnsExist)

I generally do this immediately after calling a Fill ... or even in some cases an Add since those columns would not exist on the Add.  This really is up to you and depends on if this is an isolated element of a single maintenance form or will happen for the entire BO no matter where it is used.

If it is the latter, then you may want to override the FillDataTable method on your BO.  Then call this method after you call the MyBase.FillDataTable(...) method. 

By Ertan Deniz - 5/23/2008

Any comment ?
By Trent L. Taylor - 5/23/2008

No, not really.  What do you mean?  I already gave you my comment on the previous post. Smile
By Ertan Deniz - 5/23/2008

I had thought that I had to write for every property of a class to ensure specified column exist in CurrentDataTable.

But It was only for extended properties. So, It is not hard to write.