Best way to implement “ReOrderable Collection” and Persist it to database

前端 未结 6 782
执笔经年
执笔经年 2021-01-03 12:12

My domain object :

public class MyDomainObject
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public int DisplayOrder { get; set         


        
6条回答
  •  日久生厌
    2021-01-03 12:33

    Now I'm assuming that you do want to always reorganize your list so that the DisplayOrder starts at 0 and increases without gaps, and you want this to happen automatically. You could implement your own collection type and an interface IDisplayOrderable and have the members of your type that change the list also automaticaly update the DisplayOrder of the items in the collection. As opposed to my other answer which was about an alternative way to store the data in the datase, this answer shows how to write a client class that could make it easier to automatically synchronize the DisplayOrder in your objects with your list indexes so that when you are ready to submit the changes to the database, the DisplayOrder field is already set correctly for you.

    I think the answer is best given as some source code:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    
    interface IDisplayOrderable
    {
        int DisplayOrder { get; set; }
    }
    
    class ReorderableList : IList where T : IDisplayOrderable
    {
        List list = new List();
    
        private void updateDisplayOrders()
        {
            int displayOrder = 0;
            foreach (T t in list)
            {
                t.DisplayOrder = displayOrder++;
            }
        }
    
        public ReorderableList() { }
    
        public ReorderableList(IEnumerable items)
        {
            list = new List(items.OrderBy(item => item.DisplayOrder));
        }
    
        public void Insert(int index, T item)
        {
            list.Insert(index, item);
            updateDisplayOrders();
        }
    
        public void Add(T item)
        {
            list.Add(item);
            updateDisplayOrders();
        }
    
        public bool Remove(T item)
        {
            bool result = list.Remove(item);
            if (result)
                updateDisplayOrders();
            return result;
        }
    
        public IEnumerator GetEnumerator()
        {
            return list.GetEnumerator();
        }
    
        // TODO: Other members and methods required to implement IList...    
    }
    
    class Item : IDisplayOrderable
    {
        public string Name { get; set; }
        public int DisplayOrder { get; set; }
    }
    
    class Program
    {
        static void Main()
        {
            Item foo = new Item { Name = "foo", DisplayOrder = 0 };
            Item bar = new Item { Name = "bar", DisplayOrder = 1 };
            Item baz = new Item { Name = "baz", DisplayOrder = 2 };
    
            // Pretend this came from the database.
            IEnumerable query = new Item[] { bar, foo };
    
            // The constructor automatically reorder the elements.
            ReorderableList items = new ReorderableList(query);
            items.Add(baz);
            items.Remove(foo);
            items.Insert(1, foo);
    
            foreach (Item item in items)
                Console.WriteLine("{0} : {1}", item.Name, item.DisplayOrder);
        }
    }
    

    Output:

    bar : 0
    foo : 1
    baz : 2
    

    Perhaps this was the sort of answer you were looking for?

提交回复
热议问题