i have an entity saved on the database that has 2 relevant properties, Code and Number.
the number is just an int between 1 and 99, while the code is a string representation like "01" to "99"
the problem is that some sub-entities have a code like "0103" or "3301", which is just the parent's code it's own code.
all entities are saved on one table, there are 3 levels of hierarchy indicated only by the length of the code "00" is a level 1, "0000" is level 2, and "000000" is level 3.
I want to order them in such a way that they're presented like
- name - 01
- name - 010201
- name - 0103
- name - 02
- name - 0201
- name - 04
and so on...
where an entity with "01" is first, followed by entities that start with "01" and under each one will be entities that start with "01xx", sort of a tree hierarchy.
note that i'm using EFcore 5, .NET 5, and C# 9
what i have right now is simply
var SearchQuery = _appDbContext.Regions.AsNoTracking().AsQueryable().OrderBy(r => r.Code);
and then i use that query to generate my DTOs
ResultData = await SearchQuery.Select(r => new DTO
{
Id = r.Id,
NameCode = r.Name " - " r.Code
}).ToListAsync();
should i use a custom comparer or something else? or does this approach satisfy?
CodePudding user response:
Use IComparable :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication20
{
class Program
{
static void Main(string[] args)
{
string[] array = {"name - 01", "name - 010201", "name - 0103", "name - 02", "name - 0201", "name - 04"};
string[] sorted = array.Select(x => new Sort(x)).OrderBy(x => x).Select(x => x.numericStr).ToArray();
}
}
public class Sort : IComparable<Sort>
{
public string numericStr { get; set; }
string[] split { get; set; }
string number { get; set; }
public Sort(string input)
{
numericStr = input;
split = input.Split(new char[] { ' ' }).ToArray();
}
public int CompareTo(Sort other)
{
int minSize = Math.Min(split.Length, split.Length);
for(int i = 0; i < minSize; i )
{
int c = split[i].CompareTo(other.split[i]);
if (c != 0) return c;
}
return split.Length.CompareTo(other.split.Length);
}
}
}
CodePudding user response:
I managed to make a function that collects level 1, 2, 3 entities in 3 different Lists (after applying filters) then looping through it less than a couple of times and inserting them to a List<Entity>
according to the correct order
but @CharlesMager has clarified to me that the normal OrderBy(r => r.Code)
will have the exact same result due to the Code property not having any whitespaces.
in other words:
OrderBy(r => r.Code)
will NOT sort the string in 01
, 02
, 01xx
as I previously thought;
Rather it'll sort them in correct order such as 01
, 01xx
, 02
, 02xx
and so on.