User98743 Ответов: 1

Поиск обновления пользовательского объекта в списке


Мое приложение перебирает таблицы в моей базе данных. Для каждой таблицы, имеющей первичный ключ, необходимо знать столбцы первичного ключа.

Я с помощью GetOleDbSchemaTable для oledb, который возвращает объект DataTable, как это:
Primay_Key_Name, Table_Name, Column_Name, Ordinal
PK_ZipCode,      Cities,     ZipCode,     1
PK_ZipCode,      Cities,     ZipPlus4,    2
PK_ProjectId,    Projects,   ID           1
PK_UsersId,      Users,      ID           1
В примере показаны 3 первичных ключа. Существует 4 записи, потому что PK_ZipCode-это составной ключ с двумя столбцами, ZipCode и ZipPlus4.

Я хочу сохранить это в списке, чтобы мне не пришлось обращаться к базе данных позже, когда я буду перебирать таблицы, чтобы получить столбцы.

Какой тип списка я должен использовать? Я просмотрел 8-часовое видео PluralSight о коллекциях C# только для того, чтобы обнаружить, что строго типизированные коллекции теперь являются "устаревшими" и что вместо них я должен использовать универсальные коллекции.

Чтобы избежать просмотра другого видео, я создал объект для хранения данных. Я буду хранить его в список<primarykeyobj&ГТ;.
public class PrimaryKeyObj
{
    private string schema = null;
    private List<string> columns = new List<string> { };
    private string table = null;

    public string Schema { get => schema; set => schema = value; }
    public List<string> Columns { get => columns; set => columns = value; }
    public string Table { get => table; set => table = value; }

    public PrimaryKeyObj (string schema, string table, List<string> columns )
    {
        Schema = schema;
        Table = table;
        Columns = columns;
    }
}


В настоящее время я делаю это в 2 запросах:

(1) возвращает список ключей Primay и создает мои пользовательские объекты
(2) заполняет мой объект списком столбцов первичного ключа.

Шаг 1: Создайте список пользовательских объектов PrimaryKeyObj:
dt = dbConnection.GetOleDbSchemaTable ( OleDbSchemaGuid.Primary_Keys ,
            new Object[ ] { null , null, null } );

dv = dt.DefaultView;
dv.RowFilter = "TABLE_NAME NOT LIKE 'MSys%' and ORDINAL = 1";
dt = dv.ToTable ( );

var primarykeys = new List<PrimaryKeyObj> { };
var primarykeycolumns = new List<string> { };

for ( int i = 0 ; i < dt.Rows.Count ; i++ )
{
    string schema = dt.Rows[ i ][ "TABLE_SCHEMA" ].ToString ( );
    string table = dt.Rows[ i ][ "TABLE_NAME" ].ToString ( );
    PrimaryKeyObj pko = new PrimaryKeyObj ( schema , table, primarykeycolumns );
    primarykeys.Add ( pko );
}
Следующая часть-это то, где я застрял. Теперь, когда у меня есть список первичных ключей, мне нужно заполнить каждый из них именами столбцов первичного ключа.

Шаг 2: Пройдитесь по первичным ключам, найдите ключ в моем списке<primaykeyobj> и обновите этот ключ именами столбцов.
dt = dbConnection.GetOleDbSchemaTable ( OleDbSchemaGuid.Primary_Keys ,
			new Object[ ] { null , null , null } );                                        
dv = dt.DefaultView;
dv.Sort = "TABLE_SCHEMA, TABLE_NAME, PK_NAME, ORDINAL asc";
dv.RowFilter = "TABLE_NAME NOT LIKE 'MSys%'";                                                                                          
dt = dv.ToTable ( );

for ( int i = 0 ; i < dt.Rows.Count ; i++ )
{
	string schema = dt.Rows[ i ][ "TABLE_SCHEMA" ].ToString ( );
	string table = dt.Rows[ i ][ "TABLE_NAME" ].ToString ( );
	string column = dt.Rows[ i ][ "COLUMN_NAME" ].ToString ( );

	PrimaryKeyObj PkObj = {Do something to return the PrimaryKeyObj that has this schema and table} 
	pko.Columns.Add ( column );						
}


Что я уже пробовал:

Я пробовал писать это как словарь, и как список "строка", чтобы держать схему, список "строка", чтобы держать таблицу, но потом застрял на том, как привести столбцы в складку. Я пробовал много других вещей, но уже после 4 утра, поэтому, пожалуйста, просто спросите меня, нужна ли вам еще какая-нибудь информация.

1 Ответов

Рейтинг:
2

Maciej Los

Я не уверен, что правильно вас понял, но.....

Если вы хотите получить список таблиц и их столбцов с информацией о первичных ключах, вам придется изменить свой PrimaryKeysObj таким образом:

public class PrimaryKeyObj
{
 	private string schema = string.Empty;
	private string sPK = string.Empty;
    private List<string> columns = new List<string>();
    private string table = string.Empty;

    public string Schema { get => schema; set => schema = value; }
    public List<string> Columns { get => columns; set => columns = value; }
    public string Table { get => table; set => table = value; }
	public string PrimaryKey { get => sPK; set => sPK = value; }

    public PrimaryKeyObj (string schema, string table, string sPrimaryKey, List<string> columns )
    {
        Schema = schema;
        Table = table;
		PrimaryKey = sPrimaryKey;
        Columns = columns;
    }
}


Это должно помочь вам хранить всю информацию.
Например:
List<PrimaryKeyObj> primarykeys =
    dt.AsEnumerable()
    .GroupBy(x=>x.Field<string>("TABLE_NAME"))
    .Select(grp => new PrimaryKeyObj
    (
        grp.Select(a=>a.Field<string>("TABLE_SCHEMA")).First(),
        grp.Key,
        grp.Select(a=>a.Field<string>("PRIMARY_KEY_NAME")).First(),
        grp.Select(c=> c.Field<string>("COLUMN_NAME")).ToList()
    )).ToList();


Теперь, ваше primarykeys следует хранить список PrimaryKeyObj.