0

SQLite データベースからすべてのテーブルを一覧表示しようとしていますが、必要なのは通常のテーブルだけで、システム テーブルは必要ありません。ループ中に foreach を使用して行を削除しようとしましたが、例外が発生します。どこが間違っているのか本当にわからないので、誰かがここで間違っていることを指摘してもらえますか。

私の唯一の考えは、ループ中に DataTable から削除できないということですが、そうでなければこの問題にどのようにアプローチするかわかりません。

データベースには現在、3 つの通常テーブルと 1 つのシステム テーブルの 4 つのテーブルが含まれています

コード:

        SQLiteConnection connection = new SQLiteConnection("Data Source=db.sqlite");

        connection.Open();

        DbTables = connection.GetSchema("Tables");

        foreach (DataRow row in DbTables.Rows)
        {
            Console.WriteLine(row[3].ToString());

            if (row[3].ToString() == "SYSTEM_TABLE")
                DbTables.Rows.Remove(row);
        }

        connection.Close();

例外:

System.Windows.Data Error: 17 : Cannot get 'Main' value (type 'MainViewModel') from '' (type 'ViewModelLocator'). BindingExpression:Path=Main; DataItem='ViewModelLocator' (HashCode=65325907); target element is 'MainWindow' (Name=''); target property is 'DataContext' (type 'Object') TargetInvocationException:'System.Reflection.TargetInvocationException: Property accessor 'Main' on object 'DatabaseExplorer.ViewModel.ViewModelLocator' threw the following exception:'Exception has been thrown by the target of an invocation.' ---> System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.InvalidOperationException: Collection was modified; enumeration operation might not execute.
   at System.Data.RBTree`1.RBTreeEnumerator.MoveNext()
   at DatabaseExplorer.ViewModel.MainViewModel..ctor(IDataService dataService) in Project\ViewModel\MainViewModel.cs:line 61
   --- End of inner exception stack trace ---
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
   at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.ConstructorInfo.Invoke(Object[] parameters)
   at GalaSoft.MvvmLight.Ioc.SimpleIoc.MakeInstance[TClass]()
   --- End of inner exception stack trace ---
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
   at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
   at System.Delegate.DynamicInvokeImpl(Object[] args)
   at System.Delegate.DynamicInvoke(Object[] args)
   at GalaSoft.MvvmLight.Ioc.SimpleIoc.DoGetService(Type serviceType, String key)
   at GalaSoft.MvvmLight.Ioc.SimpleIoc.GetInstance[TService]()
   at DatabaseExplorer.ViewModel.ViewModelLocator.get_Main() in Project\ViewModel\ViewModelLocator.cs:line 54
   --- End of inner exception stack trace ---
   at System.ComponentModel.ReflectPropertyDescriptor.GetValue(Object component)
   at MS.Internal.Data.ValueTable.GetValue(Object item, PropertyDescriptor pd, Boolean indexerIsNext)
   at MS.Internal.Data.PropertyPathWorker.GetValue(Object item, Int32 level)
   at MS.Internal.Data.PropertyPathWorker.RawValue(Int32 k)'

if 句を削除したときのコンソール出力:

SYSTEM_TABLE
table
table
table

前もって感謝します!

4

1 に答える 1

3

列挙中にコレクションを変更することはできません。したがって、foreachループを変更するかfor、削除する行で埋められる一時コレクションを作成して後で削除することができます。

最初のアプローチ(テストが必要です。現在、コンピューターの前ではありません):

for (int i = DbTables.Rows.Count; i >=0 ; i--)
{
    if (DbTables.Rows[i].ToString() == "SYSTEM_TABLE")
         DbTables.Rows.RemoveAt(i);
}

2 番目のアプローチ:

DbTables = connection.GetSchema("Tables");

var rowsToBeRemoved = new List<DataRow>();

foreach (DataRow row in DbTables.Rows)
{
    Console.WriteLine(row[3].ToString());

    if (row[3].ToString() == "SYSTEM_TABLE")
       rowsToBeRemoved.Add(row);
}

foreach DataRow row in rowsToBeRemoved)
{
    DbTables.Rows.Remove(row);
}
于 2013-05-29T09:31:08.227 に答える