Это может быть не самый эффективный способ, но я решил поставить однострочный (фактически двухстрочный). Обе версии будут работать с произвольными иерархическими вложенными списками и будут использовать языковые возможности (Python3.5) и рекурсию.
def make_list_flat (l):
flist = []
flist.extend ([l]) if (type (l) is not list) else [flist.extend (make_list_flat (e)) for e in l]
return flist
a = [[1, 2], [[[[3, 4, 5], 6]]], 7, [8, [9, [10, 11], 12, [13, 14, [15, [[16, 17], 18]]]]]]
flist = make_list_flat(a)
print (flist)
Выход:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]
Это работает на глубине первый способ. Рекурсия идет до тех пор, пока не найдет элемент, не являющийся списком, затем расширяет локальную переменную flist
и затем возвращает ее родительскому элементу. Всякий раз, когда возвращается flist
, он расширяется до родительского flist
в понимании списка. Поэтому в корне возвращается плоский список.
Вышеописанное создает несколько локальных списков и возвращает их, которые используются для расширения списка родителя. Я думаю, что путь для этого может создать gloabl flist
, как показано ниже.
a = [[1, 2], [[[[3, 4, 5], 6]]], 7, [8, [9, [10, 11], 12, [13, 14, [15, [[16, 17], 18]]]]]]
flist = []
def make_list_flat (l):
flist.extend ([l]) if (type (l) is not list) else [make_list_flat (e) for e in l]
make_list_flat(a)
print (flist)
Выход снова
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]
Хотя я не уверен в этом время об эффективности.
Вам нужно назначить соединение с SqlCommand
, вы можете использовать конструктор или свойство :
cmd.InsertCommand = new SqlCommand("INSERT INTO Application VALUES (@EventLog, @TimeGenerated, @EventType, @SourceName, @ComputerName, @InstanceId, @Message) ");
cmd.InsertCommand.Connection = connection1;
Я сильно рекомендуем использовать using-statement
для любого типа, реализующего IDisposable
, например SqlConnection
, он также закроет соединение:
using(var connection1 = new SqlConnection(@"Data Source=.\sqlexpress;Initial Catalog=syslog2;Integrated Security=True"))
{
SqlDataAdapter cmd = new SqlDataAdapter();
using(var insertCommand = new SqlCommand("INSERT INTO Application VALUES (@EventLog, @TimeGenerated, @EventType, @SourceName, @ComputerName, @InstanceId, @Message) "))
{
insertCommand.Connection = connection1;
cmd.InsertCommand = insertCommand;
//.....
connection1.Open();
// .... you don't need to close the connection explicitely
}
}
Кроме того, t нужно создать новое соединение и DataAdapter
для каждой записи в foreach
, даже если создание, открытие и закрытие соединения не означает, что ADO.NET будет создавать, открывать и закрывать физическое соединение, но просто смотрит в пул соединений для доступного соединения. Тем не менее это лишние накладные расходы.
Фактически эта ошибка возникает, когда сервер делает соединение, но не может построить из-за сбоя при идентификации идентификатора функции соединения. Эту проблему можно решить, набрав функцию соединения в коде. Для этого я беру простой пример. В этом случае функция con может отличаться.
SqlCommand cmd = new SqlCommand("insert into ptb(pword,rpword) values(@a,@b)",con);
Несколько вещей здесь не так.
SqlCommand
вместо SqlDataAdapter
? SqlCommand
) требуется именно то, что сообщение об ошибке сообщает ему, что оно отсутствует: активное соединение. Я настоятельно рекомендую использовать C # / C ++, Учебник по SQL Server.
Вы не инициализируете соединение. Вот почему такая ошибка приходит к вам.
Ваш код:
cmd.InsertCommand = new SqlCommand("INSERT INTO Application VALUES (@EventLog, @TimeGenerated, @EventType, @SourceName, @ComputerName, @InstanceId, @Message) ");
Исправленный код:
cmd.InsertCommand = new SqlCommand("INSERT INTO Application VALUES (@EventLog, @TimeGenerated, @EventType, @SourceName, @ComputerName, @InstanceId, @Message) ",connection1);
просто попробуйте это.
вам нужно открыть соединение с помощью connection.open()
на объекте SqlCommand.Connection
перед выполнением ExecuteNonQuery()
Открытие и закрытие соединения занимает много времени. И используйте «использование», как предложил другой член. Я немного изменил код, но поставил SQL-создание и открытие и закрытие OUTSIDE вашей петли. Который должен немного ускорить выполнение.
static void Main()
{
EventLog alog = new EventLog();
alog.Log = "Application";
alog.MachineName = ".";
/* ALSO: USE the USING Statement as another member suggested
using (SqlConnection connection1 = new SqlConnection(@"Data Source=.\sqlexpress;Initial Catalog=syslog2;Integrated Security=True")
{
using (SqlCommand comm = new SqlCommand("INSERT INTO Application VALUES (@EventLog, @TimeGenerated, @EventType, @SourceName, @ComputerName, @InstanceId, @Message) ", connection1))
{
// add the code in here
// AND REMEMBER: connection1.Open();
}
}*/
SqlConnection connection1 = new SqlConnection(@"Data Source=.\sqlexpress;Initial Catalog=syslog2;Integrated Security=True");
SqlDataAdapter cmd = new SqlDataAdapter();
// Do it one line
cmd.InsertCommand = new SqlCommand("INSERT INTO Application VALUES (@EventLog, @TimeGenerated, @EventType, @SourceName, @ComputerName, @InstanceId, @Message) ", connection1);
// OR YOU CAN DO IN SEPARATE LINE :
// cmd.InsertCommand.Connection = connection1;
connection1.Open();
// CREATE YOUR SQLCONNECTION ETC OUTSIDE YOUR FOREACH LOOP
foreach (EventLogEntry entry in alog.Entries)
{
cmd.InsertCommand.Parameters.Add("@EventLog", SqlDbType.VarChar).Value = alog.Log;
cmd.InsertCommand.Parameters.Add("@TimeGenerated", SqlDbType.DateTime).Value = entry.TimeGenerated;
cmd.InsertCommand.Parameters.Add("@EventType", SqlDbType.VarChar).Value = entry.EntryType;
cmd.InsertCommand.Parameters.Add("@SourceName", SqlDbType.VarChar).Value = entry.Source;
cmd.InsertCommand.Parameters.Add("@ComputerName", SqlDbType.VarChar).Value = entry.MachineName;
cmd.InsertCommand.Parameters.Add("@InstanceId", SqlDbType.VarChar).Value = entry.InstanceId;
cmd.InsertCommand.Parameters.Add("@Message", SqlDbType.VarChar).Value = entry.Message;
int rowsAffected = cmd.InsertCommand.ExecuteNonQuery();
}
connection1.Close(); // AND CLOSE IT ONCE, AFTER THE LOOP
}
дважды щелкните по вашей форме, чтобы создать событие form_load. Затем внутри этого события write command.connection = «ваше имя соединения»;