有时候我们会做一个拖拽数据排序然后更新到数据库的功能(数据量不大的情况下),今天试着写了一个排序的demo,自己记录一下,大牛们会有更好的方案可以一起探讨;
场景:管理后台对一些分类数据进行拖拽重新排序,客户端拖动的时候,获得所在原位置索引,和拖动结束后的位置索引,后端收到位置信息,然后对数据进行循环重新编顺序号,然后再对数据进行更新,PS:和客户端写VUE的同事沟通好,我这里的数据索引都是从0开始的;
方案1 实现如下:
static async Task Main(string[] args)
{
//方案1:循环开始和结束位置,逐个设置Sort排序值
Console.WriteLine("=============生成测试数据==============");
List<test> list = new List<test>();
for (int i = 0; i < 10; i++)
{
var item = new test { sort = i, val = "测试" + i };
list.Add(item);
Console.WriteLine(item);
}
//设置位置调换
int olds = 3;//旧位置
int news = 6;//新位置
// 旧位置 > 新位置 用于偏移量
bool isLess = olds > news;
//取开始位置 旧位置>新位置 则从新位置开始 否则取反
int start = (isLess ? news : olds);
//结束的位置 旧位置>新位置 则结束位置为新位置+1 否则到旧位置处结束
int end = isLess ? olds : news + 1;
//递增量 旧位置>新位置 则地增量为1 从低往高 否则 地增量从 -1 开始,原因是旧位置从低往高 自己那个位置不算所以循环时需要少计算1个递增量
int index = isLess ? 1 : -1;
Console.WriteLine("===========================");
Console.WriteLine($"->本次执行 :从旧位置:{olds} 到新位置:{news} ");
Console.WriteLine("=============打印过程==============");
//List<test> updatelist = new List<test>();//记录需要更新的数据
for (int i = start; i < end; i++)
{
Console.WriteLine($"{i}:{ (start + index)}");
list[i].sort = (start + index);
index++;
//updatelist.Add(list[i]);//加入待更新
}
list[olds].sort = news;//设置旧的索引的顺序号为新位置索引【要最后赋值,否则会在从低改到高处时索引被重新修改导致错误。如果不放在这里,可以把结束后list[end].sort=(end+1) 】
Console.WriteLine("=============调换位置后打印结果==============");
list.OrderBy(x => x.sort).ToList().ForEach(x =>
{
Console.WriteLine(x);
});
//执行批量更新方法
//db.UpadteRange<test>(updatelist) ;
}
打印结果:
从低到高
从高到低:
方案2: 用 List 集合内置方法,删除原来数据,再插入指定位置然后重新排序,这种方案也是比较简单相比第一种方案是比较推荐的;
static async Task Main(string[] args)
{
Console.WriteLine("=============生成测试数据==============");
List<test> list = new List<test>();
for (int i = 0; i < 10; i++)
{
var item = new test { sort = i, val = "测试" + i };
list.Add(item);
Console.WriteLine(item);
}
//设置位置调换
int olds = 9;//旧位置
int news = 5;//新位置
var entity = list[olds]; //获得当前需要修改位置的集合子对象
list.Remove(entity); //从集合中先删除对象
list.Insert(news, entity);//然后再指定的位置插入对象
//循环从新编顺序号
int index = 0;
list.ForEach(x =>
{
x.sort = index;
index++;
});
Console.WriteLine("=============调换位置后打印结果==============");
list.ForEach(x => { Console.WriteLine(x); });
}
打印结果是一样的就不贴图了
补充下测试实体类:
public class test
{
public override string ToString()
{
return $"sort:{sort} , val:{val}";
}
public int sort { get; set; }
public string val { get; set; }
}