I have data arranged in this order in sql.
Now, I want to order this list with both QuestionDataTypeId and DisplayOrder, but want this QuestionDataTypeId = 0 at last. so finally result will be like first row = 6 then 7 then 8 and then 1 to 5.
I want to achieve this with C# and linq.
What I have tried so far?
here is my code but it's not working.
var data = entity
.OrderByDescending(m => m.QuestionDataTypeId == 0)
.ThenBy(m => m.QuestionDataTypeId)
.ThenBy(m => m.DisplayOrder);
I have fixed this with merging 2 different variables sorted separately for QuestionDataTypeId = 0 and all other QuestionDataTypeId, but just want to know what will be the proper linq for this case in single line.
any help would be really appreciated. thanks!
CodePudding user response:
You can write your own comparer for OrderBy
Sample data structure:
public record Table
{
public Table(int qdtId, int displayOrder, string text)
{
QuestionDataTypeId = qdtId;
DisplayOrder = displayOrder;
Text = text;
}
public int QuestionDataTypeId { get; set; }
public int DisplayOrder { get; set; }
public string Text { get; set; }
}
public class TableComparer : IComparer<Table>
{
public int Compare(Table? x, Table? y)
{
if(x.QuestionDataTypeId!= 0 && y.QuestionDataTypeId!=0 || x.QuestionDataTypeId == 0 && y.QuestionDataTypeId == 0)
{
return y.QuestionDataTypeId.CompareTo(x.QuestionDataTypeId);
}
return x.QuestionDataTypeId == 0 && y.QuestionDataTypeId != 0 ? int.MinValue : int.MaxValue;
}
}
Then in the code:
List<StringConcatBug.Table> list = new()
{
new(0, 1, "Comfortable"),
new(0, 2,"attainable"),
new(0, 3,"recent goal"),
new(0, 4,"comfortable"),
new(2, 2,"Last Name"),
new(3, 3,"Email"),
new(0, 5, "feeling"),
new(1, 1, "First Name"),
};
var ordered = list.OrderByDescending(t=>t,new TableComparer());
foreach(var v in ordered) { Console.WriteLine(v);}
Output
Table { QuestionDataTypeId = 1, DisplayOrder = 1, Text = First Name }
Table { QuestionDataTypeId = 2, DisplayOrder = 2, Text = Last Name }
Table { QuestionDataTypeId = 3, DisplayOrder = 3, Text = Email }
Table { QuestionDataTypeId = 0, DisplayOrder = 1, Text = Comfortable }
Table { QuestionDataTypeId = 0, DisplayOrder = 2, Text = attainable }
Table { QuestionDataTypeId = 0, DisplayOrder = 3, Text = recent goal }
Table { QuestionDataTypeId = 0, DisplayOrder = 4, Text = comfortable }
Table { QuestionDataTypeId = 0, DisplayOrder = 5, Text = feeling }
CodePudding user response:
I usually use this algorithm
var mult=100000; // You can select a different number depending how many records of
// the same type you expecting; Numbers should not overlap
var data = entity
.OrderBy(m => (m.QuestionDataTypeId*mult m.DisplayOrder))
.....
CodePudding user response:
Try replace QuestionDataTypeId where value = 0
.OrderBy(x=>x.QuestionDataTypeId==0?int.MaxValue:x.QuestionDataTypeId)
.ThenBy(t=>t.DisplayOrder)