Bind Source Logistics, Child Tables

JaedenRuiner

Well-known member
Joined
Aug 13, 2007
Messages
340
Programming Experience
10+
Well,

With the nature of relational databases, there are often Primary Keys and Foreign Keys, and in the past I have not had to utilize programming to work with databases, but direct SQL access points, etc. (Sql*Plus, etc).

I've come quite a ways since then and have my DB designed, all my relationship ducks are in their rows, and the forms are all designed, but I noticed something that made me question a little logistical handling with regards to ForiegnKeys.

Database
VB.NET:
tbl_Customers
  Cust_ID PK
  Name nvarchar(50)

tbl_BOL
  BOL_ID PK
  Customer (FK_tblBOL_tblCustomers : Cust_ID -> Customer)


On the form I have a DGV, which is bound to a BindingSource:
VB.NET:
  private _dsMyDB
  private dgv_Customers
  private bind_Customers
  
  bind_Customers.DataSource = _dsMyDB
  bind_Customers.DataMember = "tbl_Customers"
  dgv_Customers.DataSource = bind_Customers

Pretty straight forwards. On the same form, i have a secondary DGV but this is the point of contention:
VB.NET:
  private dgv_BOL
  private bind_BOL

  bind_BOL.DataSource = _dsMyDB
  bind_BOL.DataMember = "tbl_BOL"

Which is the best method to use for the linkage of the dgv_BOL to the current selection in the dgv_Customers:


  • VB.NET:
      dgv_BOL.DataSource = bind_BOL
      sub dgv_Customer_OnRowSelect() 
         bind_BOL.Filter = "Customer = '" & CurrentRowCustId & '"
      end sub
  • Or
    VB.NET:
      dgv_BOL.DataSource = bind_Customer
      dgv_BOL.DataMember = FK_tblBOL_tblCustomer

I notice this initially, and was curious if the FK assignment to the DataMember will automatically follow the parent bind source or not. (Currently I am using a BindingNavigator to manipulate the different bind_Sources etc, i'm just curious as to the proper usage of that FK_* entry within a Parent BindingSource)

Thanks
 
Thanks

It wasn't precisely what I was looking for, but it did answer quite a few other questions in the process.

the answer was definitely Set The Source of the Child to the same as the Parent and the Member to the Foreign Key. (i had to run through the quick test in visual forms design as they did in that video to find that answer)...

The reason for me is that I'm doing a lot of this programmatically. You may (or may not) disagree, Basically my app initially asks for a login to the database, (since my connection string does not retain user/password information) So to handle this instead of having to constantly re-assign the connection string to each Datatable/TableAdapter whatever uses a SqlConnection, my wrapper class handles all of that for me. Thus my TA's and DT's are interconnected for quicker and easier access in my application forms.

This being said, the form designers do not allow me to set the DataSource of the binding sources to MyWrapperClass.MyDataSet,
so I have to do them in the code. This allows me (again you may or may not disagree) on application wide DB Connection/Dataset (as there is only need for One Dataset throughout the use of my app, and since I have several forms that access it, I prefer not to have 6 Adapters, 6 Binding Sources, with a TA manager and Dataset on EVERY form. That's just a waste of space, and too confusing in the long run.

*Shrug*
But thanks for pointing out those videos, those will come in VERY handy, and have answered quite a few of my other posted questions already.

Gracias
 
Thanks
the answer was definitely Set The Source of the Child to the same as the Parent and the Member to the Foreign Key. (i had to run through the quick test in visual forms design as they did in that video to find that answer)...

Where N tables exist in cascading relation fashion, you ensure that each subsequent child is set to have its parent bs as a datasource, with the datamember being the string name of the relation exposed that links the two tables


So to handle this instead of having to constantly re-assign the connection string to each Datatable/TableAdapter whatever uses a SqlConnection, my wrapper class handles all of that for me. Thus my TA's and DT's are interconnected for quicker and easier access in my application forms.
I cant believe youre going to all this effort when it's relatively easy to just one-time change the connection string in use across the entire app

This being said, the form designers do not allow me to set the DataSource of the binding sources to MyWrapperClass.MyDataSet,
Indeed. DataSets contain no data.

That said, you probably didnt add the MyWrapperClass.MyDataSet as an object datasource, then you'd be able to bind to it


I prefer not to have 6 Adapters, 6 Binding Sources, with a TA manager and Dataset on EVERY form. That's just a waste of space, and too confusing in the long run.
But you have no problem using 10 labels, 7 textboxes, 2 datetimepickers and a checkbox on a form? That's so confusing. Why not jsut make EVERYTHING a textbox?

Different tools for differnet jobs. The MyXXXTableAdapter, and its associated MyXXXdatatable are for the MyXXX table in the db. That is all they do, all they are supposed to. If you wanna read and write that table, thats what you have on your form, and all the code is optimized towards that. THe BS remains generic but its a dumb component. all it does is filter and sort stuff, maintaining position/location within the data. It doesnt need typing.. However, one man, one job. You cannot expect to change one bindingsource all the time just to avoid cluttering the form (aside form the fact tha tit wont work) - each has an independent role and trying to cut down on the numbe rof them is about as logical as trying to get by declaring only one Dim tmpStr as String at the top of your form and never dimming another string. It doesnt make sense and isnt good coding practice

I suspect that you'll eventually become a martyr to some weird coding hypocrisy whereby you try to "simply" things so much they are no longer understandable, yet your "simply" coded forms will contain many repeated "unsimplified" elements.. and you end up with an inconsistent mess.

Suffice to say, if you ahve a form with tens of DT, TA, BS, then you probably have your data design too far normalised
 
Indeed. DataSets contain no data.
That said, you probably didnt add the MyWrapperClass.MyDataSet as an object datasource, then you'd be able to bind to it
Ye of little faith. My comment was not that the DataSets contain no data. I already HAVE added MyWrapperClass as a datasource, but you can't set the Datasource to a Property within the Data Source Object. So DataMember would thus be MyDataSet, and that's not the way it works. Datasource is DataSet, and Datamember is the table or other such sub entry.

But you have no problem using 10 labels, 7 textboxes, 2 datetimepickers and a checkbox on a form? That's so confusing. Why not jsut make EVERYTHING a textbox?
*sigh*. A visual component has to be on the form to enter the data. Whether I use one or seven dependent on the task. But when MainForm opens AdminForm, and AdminForm opens IMportForm, and MainForm also Opens SettingsForm, and they all need data access, constantly, it is best to have a GLOBAL variable that points to everything, then to have 27 of the same thing over and over. The idea of OOP and modular programming is to write code once and reuse it. That is precisely what i'm doing.

Different tools for differnet jobs. The MyXXXTableAdapter, and its associated MyXXXdatatable are for the MyXXX table in the db. That is all they do, all they are supposed to. If you wanna read and write that table, thats what you have on your form, and all the code is optimized towards that. THe BS remains generic but its a dumb component. all it does is filter and sort stuff, maintaining position/location within the data. It doesnt need typing.. However, one man, one job. You cannot expect to change one bindingsource all the time just to avoid cluttering the form (aside form the fact tha tit wont work) - each has an independent role and trying to cut down on the numbe rof them is about as logical as trying to get by declaring only one Dim tmpStr as String at the top of your form and never dimming another string. It doesnt make sense and isnt good coding practice
  • First off, I'm well aware of the purposes for each of the typed adapters as well as each of the typed datatables and everything else that is built in. But that still requires me to interface with it 20 times in 20 ways. I Wrapped how I will always access this DB into a wrapper that wraps up my TypedAdapter and TypedDatatable, as well as handling the Untyped datatables that can be user added to the same DB in the same DS. That way, in every form, every usage of this db I know that MyWrapper.Refresh() refreshes all the DataTables with their current DB value, and so on and so fourth. The calls to TA.Fill() are written once, inside my wrapper and its done. That is good coding practice
  • Secondly, I may or may not dim a second string, but if I need a tmpStr and thats what it is there for I wouldn't waste time dim-ing a second unless I needed two tmpStrs. When I need to retain what the data is in the tmp str, well then I declare a variable to be persistent, but otherwise why waste the time. (VB Programmers need to wake up and smell the Pointers - EVERYTHING IS A POINTER, whether we see it or not)
  • Thirdly, it does work and works quite well thank you.
I do very much appreciate all the help you wondrous people here provide me, answering particular questions in such an manner that for the majority of the time I can speed along through my development. You are all irreplaceable, and I am only able to complete my work because of the help you provide.
But...
I suspect that you'll eventually become a martyr to some weird coding hypocrisy whereby you try to "simply" <simplify?> things so much they are no longer understandable, yet your "simply" coded forms will contain many repeated "unsimplified" elements.. and you end up with an inconsistent mess.
Because I haven't told you everything, and you only see a fraction of what I do, you think you know me? Do you think I even care? Most of the time I don't even post my real question because I get people like you trying to judge my coding practices. I work in theory, and I work in dozens of languages on a weekly basis, so when I ask about syntax or language specific idiosyncrasies I don't want to go into details. They are unnecessary for those who understand the theory of all Language Structure and Programming Logic and can actually the same concepts and explain them in C++, Pascal, VB, or Fortran . I would ask that if you don't like how I do things, keep it to yourself. I do not judge others in a similar manner. "If you don't have anything nice to say..."

Peace,
 
Ye of little faith. My comment was not that the DataSets contain no data. I already HAVE added MyWrapperClass as a datasource, but you can't set the Datasource to a Property within the Data Source Object. So DataMember would thus be MyDataSet, and that's not the way it works. Datasource is DataSet, and Datamember is the table or other such sub entry.
DataSource can me a member, but DataMember cannot be a source:

myCombo.DataSource = myDataSet.MyDataTable

or

myCombo.DataSource = myDataSet
myCombo.DataMember = "MyDataTable"

but not:

myCombo.DataMember = myDataSet.MyDataTable



The idea of OOP and modular programming is to write code once and reuse it. That is precisely what i'm doing.
While you understand correctly one of the design goals of OOP, it is not precisely what you are doing. What you are precisely doing is attempting to use one object everywhere. The notion of objectifying for code reuse is e.g. use in other projects. Microsoft wrote FileReader for example, so you could read any file. They didnt hard code it to only read a file at c:\temp\afile.txt - so you can reuse their code. That is what is meant by reusing code. At the moment, to offer an analogy of trying to create one object and use it everywhere, you might as well make everything in your app static, which basically leads to a procedural program; not oo!
You accept that you'll have 27 textboxes on a form.. why do that? Why not go to massive effort to have only ONE textbox, and then paint pictures that look like all other textboxes, and just move the one text box around to accept data entry.. Can you see what i'm getting at here.. the work you go to is massive, just to "reuse" that one textbox, because "it's oo" (it isnt..)

Now, I'm not going to get into lengthy debate about this.. let's just leave it as:

Global variables are not OO
In OO, you create objects PLURAL, lots of them


That way, in every form, every usage of this db I know that MyWrapper.Refresh() refreshes all the DataTables with their current DB value
So every form your user opens causes every bit of data, relevant or irrelevant to be downloaded from the database? Eek! Do you read the entire contents of the hard disk too?

That is good coding practice
Sorry, but i disagree. Good coding practice is:

Not to lump every unrelated thing together in one place (encapsulation)
Not to perform operations that arent necessary in the interests of making a low hit on external resources



I wouldn't waste time dim-ing a second unless I needed two tmpStrs.
But you bang on about good coding practice above, and I can guarantee that dimming one tmp variable at the top then using it everywhere is incredibly poor programming practice, and totally kills the self-documenting ability of good modular code.
Additionally, exactly how much time do you think we are going to be wasting here?

tmpStr = myString.Replace("a","b")
vs
Dim aToBStr As String = = myString.Replace("a","b")

BOTH operations require a new string to be created which, in computing terms, is aeons longer operation than that of dimming a variable..

It further wouldnt surprise me if MS had made a coding optimisation where they have a few unnamed variables lying around already dimmed to take on your Dim aToB role; i.e. no dimming at all takes place. If you cant conceptualise this, imagine writing your code so that every method contains aDim tmpStr, and the framework runtime could see that they were all named the same and had very short lifespans.. it could pool one or two string variables and reuse them

MS already take steps such as moving Dims out of loops (just write your code in-loop, the compiler will move the dim out so a re-dim doesnt happen every lop pass)


Here's another good coding practice for you:
Name your variables sensibly and dim them as close to their point of use as is practical (scope sensibility)


When I need to retain what the data is in the tmp str, well then I declare a variable to be persistent,
The only time this should occur is when the data is an asset of the object, so it would be a property with a sensible name and.. blah.. see above..


(VB Programmers need to wake up and smell the Pointers - EVERYTHING IS A POINTER, whether we see it or not)
Pardon me if I'm remembering incorrectly, but you're not actually a VB programmer, right? Am I preaching Delphi to you? It sounds like you've got the grip of the basics, but some of the points youre labouring are a bit askew (see good coding practices observations above)


Because I haven't told you everything, and you only see a fraction of what I do, you think you know me?
Ahh.. I've met so many people like you; the computer world is full of them so.. yeah..

Do you think I even care?
Actually: no, and that's a real shame

Most of the time I don't even post my real question because I get people like you trying to judge my coding practices.
Oh, so it happens a lot then? Many people help you out, you take issue with their help or approach, and the fault must lie with all of them?

Now, i'll accept that some people don't like to be told how things are recommended to be done, so if this is a formal request for me to ignore all your future threads, I can certainly concede.


"If you don't have anything nice to say..."

"If you can't take the heat.." ;)
 

Latest posts

Back
Top