W ADO.NET jest coś takiego jak możliwość ustanowienia relacji pomiędzy dwiema tabelami, a następnie prezentacja tabeli zależnej z kontekście nadrzędnej. Można to zrealizować np. tak:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;

namespace DBTest
{
	public partial class Form1 : Form
	{
		private SqlConnection conSQL = new SqlConnection();
		private DataSet ds;

		public Form1()
		{
			InitializeComponent();
		}

		private string MakeConnectionString()
		{
			conSQL.Close();
			return "Persist Security Info=False;Data Source=.\\SQLEXPRESS2K8R2;Integrated Security=SSPI;";
		}

		private void MakeParameter(SqlCommand cmd, string Name, SqlDbType type, ParameterDirection pd, int size, string value)
		{
			SqlParameter p = cmd.Parameters.Add(Name, type);
			if (size > 0) p.Size = size;
			p.Direction = pd;
			if (value == null) p.Value = System.DBNull.Value;
			else p.Value = value;
		}

		private void button1_Click(object sender, EventArgs e)
		{
			if (conSQL.State != ConnectionState.Open)
			{
				conSQL.ConnectionString = MakeConnectionString();
				conSQL.Open();
			}
			string SQL =
				" create table #Elementy(id int, nazwa varchar(50));\n" +
				" insert into #Elementy values (1, 'Pierwszy');\n" +
				" insert into #Elementy values (2, 'Pierwszy dla pierwszego');\n" +
				" insert into #Elementy values (3, 'Drugi dla pierwszego');\n" +
				" insert into #Elementy values (4, 'Trzeci dla pierwszego');\n" +
				" insert into #Elementy values (6, 'Drugi');\n" +
				" insert into #Elementy values (7, 'Pierwszy dla drugiego');\n" +
				" insert into #Elementy values (8, 'Drugi dla drugiego');\n" +

				" create table #Składniki (id int identity(1, 1), ZestawId int, SkładnikId int);\n" +
				" insert into #Składniki values (1, 2);\n" +
				" insert into #Składniki values (1, 3);\n" +
				" insert into #Składniki values (1, 4);\n" +
				" insert into #Składniki values (6, 7);\n" +
				" insert into #Składniki values (6, 8);\n" +

				" select *\n" + // przekaż pełną listę elementów (zarówno składniki jak i zestawy)
				" from #Elementy;\n" +

				" select S.*, E.nazwa\n" + // przekaż jedynie składniki i ich związki z zestawami
				" from #Składniki S\n" +
				" inner join #Elementy E on E.id = S.SkładnikId;";

			SqlCommand cmd = new SqlCommand(SQL, conSQL);
			cmd.CommandType = CommandType.Text;
			SqlDataAdapter da = new SqlDataAdapter(cmd);
			ds = new DataSet(); // nowy obiekt na wyniki działania procedury
			da.Fill(ds); // wypełnij obiekt wynikami
			// ustanowienie relacji
			ds.Relations.Add("relation", ds.Tables[0].Columns["id"], ds.Tables[1].Columns["ZestawId"]);
			// przypisanie do gridów źródła danych
			MainGrid.DataSource = ds;//.Tables[0];
			DependendGrid.DataSource = ds;//.Tables[0];
			// wkazanie elementu, którego dane mają być prezentowane
			MainGrid.DataMember = ds.Tables[0].TableName;
			// wkazanie elementu, którego dane mają być prezentowane
			DependendGrid.DataMember = ds.Tables[0].TableName + ".relation";
		}
	}
}

Jest to kod aplikacji WinForms. Ostatnie dwie instrukcje metody button1_Click umożliwiają wskazanie danych, które mają zostać zaprezentowane na gridach. Zgodnie z definicją właściwości DataMember służy ona do wskazania (lub odczytania) nazwy listy lub tabeli, którą grid ma prezentować. Coś tu jednak nie gra. W ostatniej instrukcji nie jest bowiem wskazywana ani lista, ani tabela zawierająca dane. Jest wskazywana nazwa relacji. Co ciekawe występuje ona w kontekście nazwy tabeli, tej samej, której zawartość jest wyświetlana w MainGrid. A jednak koniec końców grid skądś wie, że ma wyświetlić nie tę właśnie tabelę, ale tabelę, która jest z nią w relacji i to jedynie w zakresie, jaki ta relacja w danej chwili definiuje. Proszę także zauważyć, że relacja został zdefiniowana w ramach DataSetu ds, a nie pierwszej jego tabeli. A jednak jest ona podawana właśnie w jej kontekście.

Przekopałem MSDN, aby odnaleźć jakieś informacje uzupełniające przeznaczenie właściwości DataMember i … nic. Wygląda na to, że jest to swojego rodzaju magiczna właściwość, której wszystkie możliwości nie są znane. Być może potrafi ona więcej cudownych rzeczy, niż tylko wskazywanie tabeli lub listy z danymi albo tabeli podrzędnej (w dodatku nie bezpośrednio, a przez wskazanie relacji). Pozostaje chyba zajrzeć do źródeł .NET, co pewnie w stosownym momencie uczynię. Na razie jednak „oczywistość” sposobu na prezentację zawartości tabeli zależnej będzie dla mnie niezgłębioną tajemnicą.