首页 > 解决方案 > 如何根据该行的 ID 从列表中删除该行?

问题描述

在过去的几天里,我一直在试图解决这个问题,但我似乎无法让它发挥作用。

所以我有一个具有这种格式的txt文件:

id;könyvcím;szerző;kiadó;kiadási év;

我正在使用这样的结构和列表:

public static List<Books> BooksList = new List<Books>();

public struct Books
{
    public int id;
    public string title;
    public string writer;
    public string publisher;
    public int published_year;
}  

而且我还将所有这些都放入一个基于这样的结构的列表中:

StreamReader booksRead = new StreamReader("konyvek.txt", Encoding.UTF8);
booksRead.ReadLine();
while (!booksRead.EndOfStream)
{
    string[] split = booksRead.ReadLine().Split(';');
    Books inRead = new Books();
    inRead.id = Convert.ToInt32(split[0]);
    inRead.title = split[1];
    inRead.writer = split[2];
    inRead.publisher = split[3];
    inRead.published_year = Convert.ToInt32(split[4]);
    BooksList.Add(inRead);
}
booksRead.Close();

例如,我想要的只是找到 ID 为 2 的行在哪里,然后从我的文本文件中删除该行。我试图获取我想要的行的索引,并从我的文本文件中删除它,但它甚至无法获取索引,我尝试使用 IndexOf、FindIndex 并尝试进行循环。我很确定我的结构对我这样使用它不满意,因为当我运行我的代码时会出现这样的错误:

System.InvalidCastException:'无法将'Books'类型的对象转换为'System.IConvertible'类型。'

这是我试图获取要删除的行的索引的方式

Books item = new Books();   
for (int i = 0; i < BooksList.Count; i++)
{
    if (Convert.ToInt32(textBox_id_delete.Text) == item.id)
    {
        RemoveAt = item.id;
    }
}
int index = BooksList.FindIndex(x => Convert.ToInt32(x) == RemoveAt);
MessageBox.Show(Convert.ToString(index));

我很确定我正在接近这个非常错误的,我会接受任何形式的帮助。

标签: c#arraysliststruct

解决方案


由于多种原因,您这样做完全错误。

首先,您将如何按照您的方式进行操作:

void Main()
{
    var filename = @"c:\myFolder\mybooklist.txt";
    // read into an enumerable
    var books = File.ReadAllLines(filename)
        .Select(x => x.Split(';'))
        .Select(x => new Book {
            Id = int.TryParse(x[0], out int bookId)?bookId:0,
            Title = x[1],
            Writer = x[2],
            Publisher = x[3],
            Published_year=int.TryParse(x[4], out int year)?year:0
        });
        
        
    // remove the one with id 2
    // and save back
    var otherBooks = books.Where(b => b.Id != 2);

    File.WriteAllLines(filename, otherBooks.Select(b => $"{b.Id};{b.Title};{b.Writer};{b.Publisher};{b.Published_year}"));
}

public struct Book
{
    public int Id;
    public string Title;
    public string Writer;
    public string Publisher;
    public int Published_year;
}

现在这有什么问题。

  1. 文本文件不是数据库,但您正在尝试将文本文件用作数据库。
  2. 对于文本文件,您实际上并没有在此处进行任何控制,无论 ID 是否唯一(可能有 N 本书的 ID 为 2)。
  3. (附带问题)您正在使用 C#,但看起来您来自另一种语言并且根本不使用命名约定。

恕我直言,您应该简单地使用数据库,例如 LiteDb 或 Sqlite 之类的嵌入式数据库。如果您想查看 LiteDb 或 Sqlite 的示例,请告诉我。

编辑:我正在添加 SQLite 和 LiteDb 示例。无论哪种情况,您都需要分别从 Nuget 添加 Sqlite.Data.Sqlite 和 LiteDB 并添加 using 语句。

如果是 SQLite,请注意您可以使用 Linq 添加一些驱动程序。我直接使用了 ADO.Net 命令,没有使用 Book 类进行映射。

LiteDB 是一个用 C# 为 C# 编写的 NoSQL 数据库,可以直接使用对象并开箱即用地支持 Linq。

样本仅显示两者的表面。


推荐阅读