В своей базе данных я создал две разные таблицы для объектов, скажем, OBJECT и ORIGINAL_OBJECT (на французском языке, например, Repere), единственная разница между ними в том, что ORIGINAL_OBJECT не имеет столбца, в котором я сохраняю сделанные изменения.
У меня есть функция, которая получает все поля:
public Repere Select_detail_repere(string query)
{
Repere det = null; ;
if (this.OpenConnection() == true)
{
IDataReader dataReader = ExecuteReader(query);
while (dataReader.Read())
{
det = new Repere();
det.Name = (dataReader["DET_NOM"] ?? string.Empty).ToString().Trim();
det.Modifies = dataReader["MODIFICATIONS"].ToString().Trim();
det.Profil = (dataReader["DET_PRF"] ?? string.Empty).ToString().Trim();
det.Matiere = (dataReader["DET_MAT"] ?? string.Empty).ToString().Trim();
det.GroupeProfil = (dataReader["DET_GRP_PRF"] ?? string.Empty).ToString().Trim();
det.Longueur = double.Parse(dataReader["LONGUEUR"].ToString().Trim());
det.Largeur = double.Parse(dataReader["DET_LARGE"].ToString().Trim());
det.Hauteur = double.Parse(dataReader["DET_HAUT"].ToString().Trim());
det.Poids = double.Parse(dataReader["DET_PDS"].ToString().Trim());
det.Angle1 = double.Parse(dataReader["ANG_AME_1"].ToString().Trim());
det.Angle2 = double.Parse(dataReader["ANG_AME_2"].ToString().Trim());
det.AngleAile1 = double.Parse(dataReader["ANG_AILE_1"].ToString().Trim());
det.AngleAile2 = double.Parse(dataReader["ANG_AILE_2"].ToString().Trim());
det.PercageString = (dataReader["PERCAGE"] ?? string.Empty).ToString().Trim();
det.ScribingString = (dataReader["SCRIBING"] ?? string.Empty).ToString().Trim();
det.Mark = (dataReader["MARK"] ?? string.Empty).ToString().Trim();
det.ContInt0 = (dataReader["CONT_INT"] ?? string.Empty).ToString().Trim();
det.ContExt0 = (dataReader["CONT_EXT"] ?? string.Empty).ToString().Trim();
det.Revision = (dataReader["REVISION"] ?? string.Empty).ToString().Trim();
}
this.CloseConnection();
}
return det;
}
Я использую одну и ту же функцию для OBJECT и OBJECT_ORIGINAL. Но когда я хочу прочитать свой OBJECT_ORIGINAL, я встречаю ошибку, в которой говорится, что поле не существует (очевидно).
Я уже встречал ту же проблему в других ситуациях, так как эта функция будет работать, только если я использую SELECT *
(если я не прочитаю все столбцы, это вернет ошибку).
До сих пор я нашел единственный способ решить эту проблему - использовать try / catch (в уловке я буду применять значение по умолчанию, например, ID=-1
), но я чувствую, что это не очень правильное решение, и ищу другой способ сделать что.
только что сделал это сейчас, но это не помогло ...
Было бы полезно указать в качестве запроса, который вы используете, но я думаю, что вы можете использовать IF COL_LENGTH('table_name','column_name') IS NOT NULL
в своем запросе.
Запрос очень простой: SELECT * FROM table1 будет работать, SELECT * FROM table2 не будет работать, поскольку столбец «MODIFICATIONS» не существует. Мне нужно поставить условие не в запросе, а когда я читаю результат
Вы можете использовать хранимую процедуру mysql и выполнять внутри нее проверку. проверьте это здесь. проверьте, существует ли столбец перед ALTER TABLE - mysql
Я уже видел это, и это не то, что я хочу, то, что он говорит в этом посте, - создать столбец, если он не существует, и я не хочу трогать его.
Ах, извините, что не поняла. Его тихие конфиденциальные манипуляции с базой данных, ага ..
Вам нужно проверить, существует ли столбец MODIFICATIONS
в устройстве чтения данных, поскольку вы не знаете его заранее.
В документация Microsoft я нашел метод под названием GetSchemaTable
.
Это даст вам таблицу данных, которая описывает метаданные столбца. Таким образом, вы можете проверить эту таблицу, чтобы увидеть, есть ли столбец с именем MODIFICATIONS
.
Я бы поставил эту проверку другим методом, чтобы она не сильно загромождала код в вашем цикле while
.
ИЛИ
Вы можете проверить этот вопрос на StackOverflow Проверьте имя столбца в объекте SqlDataReader, у которого есть более короткое решение вашей проблемы. Я думаю, что это еще более приятное и простое решение, но я нашел его (с помощью простого поиска в Google) после того, как почти завершил свой ответ выше. Вот почему я даю вам оба решения (а также немного помогу вам с документацией MS, на которую я указал в своем комментарии)
Хорошо, думаю, я понял. С помощью метода, указанного в ссылке на стек, я запускаю метод «HasColumn» (разумеется, только один раз), затем ifelse решит проблему.
Что касается ссылки на стек, я не смог понять, как она работает. Но благодаря вам я нашел ссылку на GetSchemaTable, затем на DataColumnCollection, и я думаю, что нашел что-то, это не так "коротко", как я ожидал, но это помогает, спасибо
Этот вопрос можно цитировать как "Повторяющийся", я нашел ответ на куча
public Repere Select_detail_repere(string query)
{
Repere det = null; ;
if (this.OpenConnection() == true)
{
IDataReader dataReader = ExecuteReader(query);
bool containsModification = CheckIfDataContains(dataReader, "MODIFICATIONS");
while (dataReader.Read())
{
det = new Repere();
det.Name = (dataReader["DET_NOM"] ?? string.Empty).ToString().Trim();
if (containsModification)
{
det.Modifies = dataReader["MODIFICATIONS"].ToString().Trim();
}
else
{
det.Modifies = "";
}
det.Profil = (dataReader["DET_PRF"] ?? string.Empty).ToString().Trim();
det.Matiere = (dataReader["DET_MAT"] ?? string.Empty).ToString().Trim();
...
}
this.CloseConnection();
}
return det;
}
public bool CheckIfDataContains(IDataReader dataReader,string columnName)
{
for (int i = 0; i < dataReader.FieldCount; i++)
{
if (dataReader.GetName(i).Equals(columnName, StringComparison.InvariantCultureIgnoreCase))
return true;
}
return false;
}
Мне нравится. Вместо использования цикла for
вы используете метод contains
, который просматривает все столбцы. Вы можете сократить метод, просто выполнив return columns.Contains(columnName)
вместо оператора if
, но это как раз то, что вам нравится.
спасибо, на самом деле return columns.Contains (columnName) лучше, только что отредактировал, спасибо за ваш отзыв. p.S: как вы "седеете" свои комментарии?
Для этого вы можете использовать обратные кавычки, см. stackoverflow.com/editing-help#code для справки по форматированию.
Ну просто "непринятый" ответ, как я заметил только сейчас, код не работает, на самом деле {columns.Contains (columnName)} всегда возвращает false
Contains
может быть чувствительным к регистру. Также убедитесь, что имена столбцов не повторяются, он вернет false. См. Документацию Microsoft
все еще ищу, на данный момент все мои имена столбцов - «ColumnName», «ColumnOrdinal», «ColumnSize» и т.д., кажется, я читаю определение столбцов вместо их имен.
Хорошо, нашел, мой код неправильный, и нашел ответ в стеке, сейчас отредактирую свой ответ
Хорошо, что теперь работает. Я вижу, что вы закончили с кодом, упомянутым в ссылке, которую я опубликовал в своем ответе stackoverflow.com/questions/373230/… (что нормально)
В самом деле? это ссылка, которую вы мне дали? (только что проверил, и это ...) ну, тогда я сделал это очень плохо, не знаю, почему я помню, я смотрел вашу ссылку и ничего не понял ... или я прочитал действительно плохо, или за это время я понял что-то получше, кто знает ... в любом случае спасибо за помощь Ура (тогда ваш ответ будет хорошим, пока они не укажут мой вопрос как дубликат ^^)
Вы читали документацию MSDN для
IDataReader
?