我正在尝试列出我的SQLite数据库中的所有表,但我只需要普通的表而不是系统表。我尝试使用foreach并在循环时删除行,但我得到一个例外。任何人都可以请指出我在这里做错了什么,因为我真的没有看到我出错的地方。
我唯一想到的是我在循环时无法从DataTable中删除,但我不知道如何处理这个问题。
数据库目前包含4个表,3个普通表和1个系统表
代码:
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
提前致谢!
答案 0 :(得分:3)
枚举时无法修改集合。因此,您可以将foreach
循环更改为for
,也可以创建将要删除的行的临时集合,然后将其删除。
第一种方法(需要测试,我现在不在我的电脑前):
for (int i = DbTables.Rows.Count; i >=0 ; i--)
{
if (DbTables.Rows[i].ToString() == "SYSTEM_TABLE")
DbTables.Rows.RemoveAt(i);
}
第二种方法:
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);
}