【问题标题】:Cannot remove DataRow from DataTable无法从 DataTable 中删除 DataRow
【发布时间】:2013-05-29 09:28:42
【问题描述】:

我正在尝试列出我的 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

提前致谢!

【问题讨论】:

    标签: c# sql sqlite mvvm-light


    【解决方案1】:

    枚举时不能修改集合。因此,您可以将 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);
    }
    

    【讨论】:

    • 是的,你完全正确,在我读到这篇文章后,我记得我只需要表名,所以我不需要删除它们,我应该将普通表存储在 List 中.. 很抱歉浪费您的时间,但无论如何感谢您的帮助!非常感谢!
    • 没问题,总是乐于提供一点帮助:)
    猜你喜欢
    • 2020-03-28
    • 2020-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多