How do I order a list by the value of a string minus it’s first character (in my case the first character is always a C followed by a number), while performing a database search.
I’ve tried a lot of stuff but I’m pretty much stumbling around in the dark, I’m sure someone here can solve this in a instant.
My code that works (but doesn’t do what I want):
List<Customer> customerlist = null;
try
{
customerlist = db.Customers
.Where(u => (u.Cust_ID+u.Given_Name+u.Surname).Contains(searchstring))
.OrderBy(u => u.Cust_ID)
.ToList();
}
My buggy code at the moment (which seems to me like it should work, but results in the search always returning no results):
List<Customer> customerlist = null;
try
{
customerlist = db.Customers
.Where(u => (u.Cust_ID+u.Given_Name+u.Surname).Contains(searchstring))
.OrderBy(u => Int32.Parse(u.Cust_ID.TrimStart('C')))
.ToList();
}
More details:
I have a column in my table named Cust_ID, which starts with a C and is then followed by a number without leading zeros e.g. C1, C2, … C43, … C999.
I am allowing the user to perform a search, the query of which is assigned to searchstring.
I’ve tried debugging by removing the int parse
.OrderBy(u => u.Cust_ID.TrimStart('C'))
that returns no results as well.
The original code I had in here still works to complete the search, but doesn’t sort it correctly.
.OrderBy(u => u.Cust_ID)
I tried using Replace instead of TrimStart
.OrderBy(u => u.Cust_ID.Remove(0, 1))
And this returns a result, but still doesn’t sort, and when i put the Int parse in, it stops returning a result again:
.OrderBy(u => Int32.Parse(u.Cust_ID.Remove(0, 1)))
I tried switching the int parse to:
.OrderBy(u => int.Parse(u.Cust_ID.Remove(0, 1)))
but that didn’t help.
edit:
found I was getting an exception:
System.NotSupportedException: LINQ to Entities does not recognize the method 'Int32 ToInt32(System.String)' method, and this method cannot be translated into a store expression.
at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.DefaultTranslator.Translate(ExpressionConverter parent, MethodCallExpression call)
at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq)
at System.Data.Objects.ELinq.ExpressionConverter.TypedTranslator`1.Translate(ExpressionConverter parent, Expression linq)
at System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)
at System.Data.Objects.ELinq.ExpressionConverter.TranslateLambda(LambdaExpression lambda, DbExpression input)
at System.Data.Objects.ELinq.ExpressionConverter.TranslateLambda(LambdaExpression lambda, DbExpression input, DbExpressionBinding& binding)
at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.OneLambdaTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, DbExpression& source, DbExpressionBinding& sourceBinding, DbExpression& lambda)
at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.OneLambdaTranslator.Translate(ExpressionConverter parent, MethodCallExpression call)
at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SequenceMethodTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, SequenceMethod sequenceMethod)
at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq)
at System.Data.Objects.ELinq.ExpressionConverter.TypedTranslator`1.Translate(ExpressionConverter parent, Expression linq)
at System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)
at System.Data.Objects.ELinq.ExpressionConverter.Convert()
at System.Data.Objects.ELinq.ELinqQueryState.GetExecutionPlan(Nullable`1 forMergeOption)
at System.Data.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
at System.Data.Objects.ObjectQuery`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at lab2.Controllers.DemoController.retrievecustomers() in [[Directory]]Controller.cs:line 52
I would just do the ordering on the client side. Why? Because it doesn’t increase the amount of traffic going across the network and will give you a lot more flexibility and allow you to check for dodgy values. It could be argued that it is better to do the sorting on the client anyway as it reduces server load.
Note that the AsEnumerable causes the linq query up to that point to be sent to the server and everything afterwards is done on the client.
As a side note I would add that if you don’t need to modify the list then it would be slightly more efficient to store the values in an array instead of a list.
I would also add do you really want to join CustID with their names for the search? This would cause the search term Bob to match someone called Bo Brown.
EDIT: I have changed ToArray to AsEnumerable as this is more efficient as pointed out by Branko Dimitrijevic. My apologies if it’s unethical to take parts from other answers.