Compound Primary Keys


Author
Message
Edhy Rijo
E
StrataFrame VIP (4.7K reputation)StrataFrame VIP (4.7K reputation)StrataFrame VIP (4.7K reputation)StrataFrame VIP (4.7K reputation)StrataFrame VIP (4.7K reputation)StrataFrame VIP (4.7K reputation)StrataFrame VIP (4.7K reputation)StrataFrame VIP (4.7K reputation)StrataFrame VIP (4.7K reputation)
Group: StrataFrame Users
Posts: 2.4K, Visits: 23K
Hi Charles,

I posted a sample in VB of a class I created based on the StrataListView in which I added some of the functionality we need.  Check it here:

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

Edhy Rijo

Edhy Rijo
E
StrataFrame VIP (4.7K reputation)StrataFrame VIP (4.7K reputation)StrataFrame VIP (4.7K reputation)StrataFrame VIP (4.7K reputation)StrataFrame VIP (4.7K reputation)StrataFrame VIP (4.7K reputation)StrataFrame VIP (4.7K reputation)StrataFrame VIP (4.7K reputation)StrataFrame VIP (4.7K reputation)
Group: StrataFrame Users
Posts: 2.4K, Visits: 23K
Charles R Hankey (2/2/2012)
If I understand you correctly, I would use a view that had one char column concatenating the four columns ( with datetimes changed to string ) for my listview.  Ok, that get's me a tag.  But the BO where I'm doing data entry will also need that column as a pk, no?  I think that's what autonavigate looks for is a pk.


Yes you can have a custom field property (CFP) that will have the string value of your PK combination, and you can use that CFP from that point forward anywhere in SF controls.  In your SELECT to grab the data, include the virtual column with the same name as the CFP and it will be there from you in the BO to use:
EX: "SELECT (Your PK Combination) AS cfp_MyCustomPK, * FROM MyTable"

In your BO, create a CFP and name it cfp_MyCustomPK.  Here is a sample (in VB) of one of my CFP which expect the field value from the SELECT statement:

    <Browsable(False),
     BusinessFieldDisplayInEditor(),
     Description("Transaction Reference No."),
     DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)>
     Public Overridable ReadOnly Property [cfp_ReferenceNo]() As Integer
         ' Check to see if datatable contains the custom field in
         ' case object was filled by a method that doesn't contain the field.
         Get
             Dim columnName As String = "cfp_ReferenceNo"
             If Me.CurrentDataTable.Columns.Contains(columnName) Then
                 If Not TypeOf (Me.CurrentRow.Item(columnName)) Is DBNull Then
                     Return CInt(Me.CurrentRow.Item(columnName))
                 Else
                     Return 0
                 End If
             Else
                 Return 0
             End If
         End Get
     End Property


Keep in mind, that you can tell the BO which is the PK column to use, also in the ListView you can select any field to be used for its Tag property.  There are many ways you can go with this.  If you will not be adding new records to this BO I prefer my approach of the CFP since you can use that all over the framework once you have it in the BO.

Edhy Rijo

Charles R Hankey
Charles R Hankey
Advanced StrataFrame User (960 reputation)Advanced StrataFrame User (960 reputation)Advanced StrataFrame User (960 reputation)Advanced StrataFrame User (960 reputation)Advanced StrataFrame User (960 reputation)Advanced StrataFrame User (960 reputation)Advanced StrataFrame User (960 reputation)Advanced StrataFrame User (960 reputation)Advanced StrataFrame User (960 reputation)
Group: Forum Members
Posts: 524, Visits: 30K
The whole point here is I want to sync a listview with BO.  Doesn't seem like it should be this hard, and using AutoNavigate it isn't - if there is a single PK.

But with a compound pk I am having to jump through hoops.

How can I get the BD to create the SQL Select and then get a result set that includes my 4 key fields mashed together?

I have created a cfp.  I assume that if I want to  use mykey as the tag in autonavigate in a listview I need to have it in the columns of the listview?  I'm missing something somewhere.  Will this cfp get populated when the bo is filled from the bd ?  If not, how do I get it to have a value before the listview is requeried? 

Obviously confused.

Am I creating the CFP correctly ?


        [Description("mykey"), Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public string mykey
            {
            get
                {
               string _mykey = this.Symbol + this.Cntry_code + this.from_date.ToString()+this.thru_date.ToString();
                return _mykey;
                }
            set
                {
                value =  this.Symbol + this.Cntry_code + this.from_date.ToString()+this.thru_date.ToString();
                }
            }

        /// <summary>
        /// Provider property descriptors for the custom bindable fields
        /// </summary>
        protected override FieldPropertyDescriptor[] GetCustomBindablePropertyDescriptors()
            {
            //-- Return the array of property descriptors
            return new MicroFour.StrataFrame.Business.FieldPropertyDescriptor[]
            { new ReflectionPropertyDescriptor("mykey", typeof(boiSource100Symbology))};
            }




Trent Taylor
Trent Taylor
StrataFrame Developer (10K reputation)StrataFrame Developer (10K reputation)StrataFrame Developer (10K reputation)StrataFrame Developer (10K reputation)StrataFrame Developer (10K reputation)StrataFrame Developer (10K reputation)StrataFrame Developer (10K reputation)StrataFrame Developer (10K reputation)StrataFrame Developer (10K reputation)
Group: StrataFrame Developers
Posts: 6.6K, Visits: 6.9K

OK.  A couple of things.  First, you are right in that this issomething that you can do several different ways.  To begin, there are a couple of things that Ineed to know.

  1. Is your CFP an actual field in the table or are you doing this as acustom field?
  2. If it is something stored in the table (or at least as a field in the datatable within the BO) then you can seek on it using the BO methods.

 So assuming that you have an actual field built within the BO that doeshave your CFP, then you can seek on it. That is the first thing that you need to get working before worryingabout the list.  The list is the easypart.  If you are just using the CFP as acustom field in the BO that DOESN’T have an actual field in the BO behind it,then you need to get that taken care of first. It doesn’t have to exist in the table in the database, but just in theDataTable in the BO.  The easiest way todo this would be to return it as part of a result set from a SPROC.


SELECT
               
MT.*,
                CAST((CAST(MT.mt_pkAS VARCHAR(20) + MT.mt_Code) AS VARCHAR(40) AS MyCFP
FROM MyTable AS MT


 Once you get here, it should be pretty smooth sailing.


Edited 12 Years Ago by Trent L. Taylor
Charles R Hankey
Charles R Hankey
Advanced StrataFrame User (960 reputation)Advanced StrataFrame User (960 reputation)Advanced StrataFrame User (960 reputation)Advanced StrataFrame User (960 reputation)Advanced StrataFrame User (960 reputation)Advanced StrataFrame User (960 reputation)Advanced StrataFrame User (960 reputation)Advanced StrataFrame User (960 reputation)Advanced StrataFrame User (960 reputation)
Group: Forum Members
Posts: 524, Visits: 30K
Thanks Trent.  ( and please see other question re datetime searchfields being checked by default )

This column does not currently exist, so I see where I need to add it.  I am not pulling any data initailly but letting the bd handle it.  i had thought of creating a fill method on the BO

Select *, space(24) as mykey from Symbology where 1 = 2

and call it in parentformloading just to get the structure.  I did try it at one point but I may have had something else screwed up. 

Listview is working fine.  and I see mykey there.

Currently, since I don't have the column, I'm doing this which isn't working out so well as it does not seem to be refreshing the controls on the form.

I would much prefer seek, so I will try again to add the column to the BO.  I guess my confusion is that the BD is creating the SQL select, so I'm not seeing how to use an SP or other fill method to change the structure of datatable of the BO.  I have done it directly, but I am not veyr good an manipulating the BD.



private void lvSymbology_SelectedIndexChanged(object sender, EventArgs e)

{

ListView lv = (ListView)sender;

if (!(lv.FocusedItem == null) && lv.Items.Count > 0)

{

string _mykey = lv.FocusedItem.SubItems[13].Text.Trim();

string _name = lv.FocusedItem.SubItems[2].Text;

//boiSource100Symbology1.CurrentView.Sort = "mykey";

//boiSource100Symbology1.CurrentView.Find(_mykey);

foreach (boiSource100Symbology bo in boiSource100Symbology1.GetEnumerable())

{

if (bo.mykey == _mykey)

{

string myname = bo.Name;

int idx = boiSource100Symbology1.CurrentRowIndex;

this.Refresh();

return;

}

}

}


Edhy Rijo
E
StrataFrame VIP (4.7K reputation)StrataFrame VIP (4.7K reputation)StrataFrame VIP (4.7K reputation)StrataFrame VIP (4.7K reputation)StrataFrame VIP (4.7K reputation)StrataFrame VIP (4.7K reputation)StrataFrame VIP (4.7K reputation)StrataFrame VIP (4.7K reputation)StrataFrame VIP (4.7K reputation)
Group: StrataFrame Users
Posts: 2.4K, Visits: 23K
Hi Charles,
We have to have the whole picture in order to give you the faster, shorter advice. Whistling

Lets recap:
  1. You have Browser Dialog (BD) which will return one or several records.
  2. After selecting the record you want to work with from the BD, you will show those records in a ListView in the form?
  3. You want the ListView in the form to autonavigate its BO using your Custom Field Property (CFP)
If the above is correct, in which step are you having issues?

Edhy Rijo

Trent Taylor
Trent Taylor
StrataFrame Developer (10K reputation)StrataFrame Developer (10K reputation)StrataFrame Developer (10K reputation)StrataFrame Developer (10K reputation)StrataFrame Developer (10K reputation)StrataFrame Developer (10K reputation)StrataFrame Developer (10K reputation)StrataFrame Developer (10K reputation)StrataFrame Developer (10K reputation)
Group: StrataFrame Developers
Posts: 6.6K, Visits: 6.9K
Charles, call the Refresh on the BO to refresh the controls on the page.  That updates the bindings and refreshes the contents.
Charles R Hankey
Charles R Hankey
Advanced StrataFrame User (960 reputation)Advanced StrataFrame User (960 reputation)Advanced StrataFrame User (960 reputation)Advanced StrataFrame User (960 reputation)Advanced StrataFrame User (960 reputation)Advanced StrataFrame User (960 reputation)Advanced StrataFrame User (960 reputation)Advanced StrataFrame User (960 reputation)Advanced StrataFrame User (960 reputation)
Group: Forum Members
Posts: 524, Visits: 30K
Thanks, I'll try that.

Regarding adding the column :

I called a fill method on the BO in parentformloading and saw the mykey column was now part of the currentdatatable.  The problem is that after calling the browse dialog, the currentdatatable no longer had the row.  BD creates it's own fillmethod.  How do I make sure the browse dialog either has that column or does not clobber the existing column?

Craate a view with the extra column, let the BD use that but still have the main BO get the column as I am doing with the dummy fillmethod?
Trent Taylor
Trent Taylor
StrataFrame Developer (10K reputation)StrataFrame Developer (10K reputation)StrataFrame Developer (10K reputation)StrataFrame Developer (10K reputation)StrataFrame Developer (10K reputation)StrataFrame Developer (10K reputation)StrataFrame Developer (10K reputation)StrataFrame Developer (10K reputation)StrataFrame Developer (10K reputation)
Group: StrataFrame Developers
Posts: 6.6K, Visits: 6.9K
On the BrowseDialog, use a custom view to populate the BO.  This should come back as part of the results.  You can also fill from it as well.  The contents of the browse dialog don't necessarily reflect what comes back if you build custom fields within the dialog.  Another option is to create the field when you come out of the browse in the data table itself.  I have done this before.  Just write a method that checks to see if the data column exists within the BO.  If not, create it.


if(!MyBO.CurrentDataTable.Columns.Contains("MyField"))
{
    DataColumn col = new("MyField", typeof(string));
    col.DefaultValue = string.Empty;
    MyBO.CurrentDataTable.Columns.Add(col);
}

Trent Taylor
Trent Taylor
StrataFrame Developer (10K reputation)StrataFrame Developer (10K reputation)StrataFrame Developer (10K reputation)StrataFrame Developer (10K reputation)StrataFrame Developer (10K reputation)StrataFrame Developer (10K reputation)StrataFrame Developer (10K reputation)StrataFrame Developer (10K reputation)StrataFrame Developer (10K reputation)
Group: StrataFrame Developers
Posts: 6.6K, Visits: 6.9K
On another note, you have two options on the checkbox on the date field.  Create an InfoPanel, which gives you access to the browse dialog window in which you could actually set this yourself.  The second option is for me to make a change to allow this as a new feature...which would require a new build and access to new releases.  I would go with #1 if I were you right now. Smile
GO

Merge Selected

Merge into selected topic...



Merge into merge target...



Merge into a specific topic ID...




Similar Topics

Reading This Topic

Login

Explore
Messages
Mentions
Search