【问题标题】:Autoincrement Id in list列表中的自动增量 ID
【发布时间】:2014-05-11 09:55:39
【问题描述】:

我正在寻找一种方法来为我的列表对象提供一个从 1 自动递增到(无论多少)的 ID。

这是我使用的类

public class Movie
{

    public int Id { get; set; }
    public string Title { get; set; }
    public string Director { get; set; }
}

我将把它用作这样的列表:

 public List<Movie> Movies { get; set; }

现在假设该列表包含 10 部电影,我删除了 id 为 5 的电影。我希望所有电影的 id 都更改,以便曾经有 id 6 的电影现在有 id 5。有人能指出我的方向正确吗?

【问题讨论】:

  • 您通常不想更改 ID,因为它是其他资源指向的标识符。当你改变它时,关系就会改变为另一部电影。如果您确定要更改它,请向代码展示您如何存储、读取和删除列表中的项目。

标签: c# asp.net-mvc list


【解决方案1】:

为您的电影列表创建一个包装器并让该类处理 Id 怎么样?

public class MoviesList
{
    public List<Movie> Movies;

    public MoviesList()
    {
        Movies=new List<Movie>();
    }

    public void Add(Movie movie)
    {
        var highestId = Movies.Any() ? Movies.Max(x => x.Id) : 1;
        movie.Id = highestId + 1;
        Movies.Add(movie);
    }
}

【讨论】:

  • 可能最好继承自List,然后重写add/remove方法,索引操作符就完美了
  • 谢谢!我会看看这个!
【解决方案2】:

这可能比较简单,但是为什么不使用List本身的索引作为id呢?它适用于您描述的场景。那么你就不需要 Id 类中的 Id 属性了。

如果您有一个尚未描述的更复杂的案例,您可能需要实现类似引用计数器之类的东西来跟踪所有 Movie 生命周期。

【讨论】:

  • 这正是我想做的,使用索引作为 ID,但我该怎么做呢?我可以在此操作链接中将索引作为参数传递吗? @Html.ActionLink("Delete", "Delete", "Home", new { id = Model.Movie[i].Id }
【解决方案3】:

您可以使用AddRemove 方法创建类似于自定义集合的内容。这样,您在向列表中添加新项目时也无需指定ID

public class Movies
{
    public List<Movie> List { get; set; }

    public Movies()
    {
        List = new List<Movie>();
    }

    public void Add(Movie newMovie)
    {
        newMovie.Id = List.Count > 0 ? List.Max(x => x.Id)+1 : 1;
        List.Add(newMovie);
    }

    public void Remove(Movie oldMovie)
    {
        List.Remove(oldMovie);
        List.ForEach((x) => { if (x.Id > oldMovie.Id) x.Id = x.Id - 1; });
    }
}

为了测试目的:

Movies movies = new Movies();

movies.Add(new Movie() { Director = "first", Title = "first" });
movies.Add(new Movie() { Director = "second", Title = "second" });
movies.Add(new Movie() { Director = "third", Title = "third" });
movies.Add(new Movie() { Director = "fourth", Title = "fourth" });
movies.Add(new Movie() { Director = "fifth", Title = "fifth" });

movies.Remove(movies.List[3]);

【讨论】:

  • 谢谢!但是我应该把这段代码放在哪里,在构造函数中呢?
  • 非常感谢您抽出宝贵时间!我会努力的!
【解决方案4】:

我将从List&lt;Movie&gt; 对象继承并覆盖它的基本添加/删除函数,在添加/删除时递增和重新设置值,使用列表的索引作为 id 的基础,类似这样(不是真的测试)-

    public class MovieList : List<Movie>
    {
        public new void Add(Movie m)
        {
            base.Add(m);
            m.Id = this.IndexOf(m);
        }
        public new void Remove(Movie m)
        {
            base.Remove(m);
            m.Id = -1;
            Reseed();
        }
        public new void RemoveAt(int index)
        {
            Movie m  = this[index];
            this.Remove(m);
        }
        public new int RemoveAll(Predicate<Movie> match)
        {
            List<Movie> removing = new List<Movie>();
            foreach (Movie m in this)
                if (match(m))
                    removing.Add(m);

            foreach (Movie m in removing)
            {
                this.Remove(m);
            }
            return removing.Count;
        }
        public new void RemoveRange(int index, int count)
        {
            for (int i = index; i < count; i++)
            {
                Movie m = this[i];
                this.Remove(m);
            }
        }
        public new Movie this[int index]
        {
            get
            {
                return base[index];
            }
            set
            {
                base[index] = value;
                Reseed();
            }
        }

        private void Reseed()
        {
            foreach (Movie x in this)
            {
                x.Id = this.IndexOf(x);
            }
        }
    }
    public class Movie
    {

        public int Id { get; set; }
        public string Title { get; set; }
        public string Director { get; set; }
    }

【讨论】:

    【解决方案5】:

    在 C# 代码中自动生成 Id 的最佳方式如下。

    public class Employee
        {
            public Guid Id { get; private set; } = Guid.NewGuid();
            public string EmployeeName { get; set; }
            public string Address { get; set; }
        }
    

    因此,每当您创建 Employee 类的对象时,它都会为 ID 属性分配一个唯一的 GUID,因此无需执行任何其他操作。

    【讨论】:

      猜你喜欢
      • 2020-03-09
      • 2021-05-01
      • 2018-04-11
      • 1970-01-01
      • 1970-01-01
      • 2023-04-03
      • 2021-03-03
      • 2013-07-27
      • 2011-12-05
      相关资源
      最近更新 更多