Вот начало (SQL 2005 и выше):
SELECT ta.name TableName, ind.name IndexName
from sys.tables ta
left outer join sys.indexes ind
on ind.object_id = ta.object_id
and ind.is_primary_key = 1
Для таблиц без первичных ключей IndexName имеет значение Null.
Но это просто список имен первичного ключа. Вам нужен список столбцов в ключе?
- ДОБАВЛЕНО ----------------
Вот часть утилиты, которую я однажды написал. Это перечислит все таблицы и столбцы в порядке всех существующих первичных ключей:
SELECT ta.name TableName, ind.name IndexName, indcol.key_ordinal IndexColumnOrder, col.name ColumnName
from sys.tables ta
left outer join sys.indexes ind
on ind.object_id = ta.object_id
and ind.is_primary_key = 1
left outer join sys.index_columns indcol
on indcol.object_id = ta.object_id
and indcol.index_id = ind.index_id
left outer join sys.columns col
on col.object_id = ta.object_id
and col.column_id = indcol.column_id
order by
ta.Name
,indcol.key_ordinal
Взломав это, в следующем списке будут перечислены все (и только) таблицы с первичными ключами только одного столбца:
SELECT ta.name TableName, max(col.name) ColumnName
from sys.tables ta
inner join sys.indexes ind
on ind.object_id = ta.object_id
and ind.is_primary_key = 1
inner join sys.index_columns indcol
on indcol.object_id = ta.object_id
and indcol.index_id = ind.index_id
inner join sys.columns col
on col.object_id = ta.object_id
and col.column_id = indcol.column_id
group by ta.name
having count(*) = 1
order by ta.Name
Что касается преобразования этого в C # (не моя сильная сторона), вы должны иметь возможность сделать это хранимой процедурой или просто создать и отправить запрос из своего кода.