Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
213 views
in Technique[技术] by (71.8m points)

c# - Search works on all fields except the date field

I'd like to search data by date with format (dd/MM/yyyy) for example "20/01/2021". the search works on ADDRESS and NAME fields but not on the CREATE_DATE.

This is my code :

       // search
        if (!string.IsNullOrEmpty(search))
        {
            List<string> terms = search.Split(',').ToList().ConvertAll(d => d.ToLower());

            res = res.Where(x =>
            terms.Any(
                str => x.NAME.Contains(str) ||
                x.ADDRESS.Contains(str) ||  
                x.DATE_CREATE.ToString().Contains(str)
            
            ));

            var test = res.FirstOrDefault().DATE_CREATE.ToString();
        }

This is the request :

http://localhost:6289/api/Customer?search=20/01/2021,hous

and this is the outputs of terms and test var :

enter image description here

enter image description here

and this is how the dates are saved , they dates are with datetime type

enter image description here

question from:https://stackoverflow.com/questions/65915188/search-works-on-all-fields-except-the-date-field

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Your code actually works on my machine BUT only in case I use appropriate culture settings as @JustShadow pointed out. Appropriate culture: which results a datetime.ToString() formating date in dd/MM/yyyy format. For test purpose I used "es-ES" culture for example with the following code inside your if statement:

Thread.CurrentThread.CurrentCulture = new CultureInfo("es-ES");

I suggest modifying your code according to this:

if (!string.IsNullOrEmpty(search))
{
   List<string> terms = search.Split(',').ToList().ConvertAll(d => d.ToLower());

   var originalCulture = Thread.CurrentThread.CurrentCulture;
   try
   {
      // use any locale which results a datetime.ToString() output in dd/MM/yyyy format
      Thread.CurrentThread.CurrentCulture = new CultureInfo("es-ES"); ;

      res = res.Where(x =>
      terms.Any(
         str => x.NAME.Contains(str) ||
         x.ADDRESS.Contains(str) ||
         x.DATE_CREATE.ToString().Contains(str)));

      var test = res.FirstOrDefault().DATE_CREATE.ToString();
   }
   finally
   {
      Thread.CurrentThread.CurrentCulture = originalCulture;
   }
}

This will be enough if your input will have always dd/MM/yyyy format.

Edit: You can try to use custom format string in ToString() call to achieve a working code as @bitapinches suggests. I think my solution performs better because there is no need to parse the custom format string in each comparison LINQ will execute. Here is the alternative for reference:

if (!string.IsNullOrEmpty(search))
{
   List<string> terms = search.Split(',').ToList().ConvertAll(d => d.ToLower());

   res = res.Where(x =>
      terms.Any(
      str => x.NAME.Contains(str) ||
      x.ADDRESS.Contains(str) ||
      x.DATE_CREATE.ToString(@"dd/MM/yyyy").Contains(str)));

   var test = res.FirstOrDefault().DATE_CREATE.ToString();
}


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...