简体   繁体   中英

LINQ c# searching

Hello i tried to filter results by variables this is what i tried:

private IQueryable<Student> FilterStudents(IQueryable<Student> students, StudentFilter filter)
{
    if (filter == null) return students; //No filter

    var fromDate = new DateTime();
    var toDate = new DateTime();

    if (!string.IsNullOrEmpty(filter.DealsFrom))
    {
         fromDate = DateTime.Parse(filter.DealsFrom);
    }
    if (!string.IsNullOrEmpty(filter.DealsTo))
    {
         toDate = DateTime.Parse(filter.DealsTo);
    }

    students = students.Where(
        s => ((!string.IsNullOrEmpty(filter.FirstName)) ? s.FirstName.Contains(filter.FirstName) : true
            && (!string.IsNullOrEmpty(filter.LastName)) ? s.LastName.Contains(filter.LastName) : true
            && (!string.IsNullOrEmpty(filter.Email)) ? s.Email.Contains(filter.Email) : true
            && (!string.IsNullOrEmpty(filter.Phone)) ? s.Phone.Contains(filter.Phone) : true
            && (!string.IsNullOrEmpty(filter.Comment)) ? s.Comment.Contains(filter.Comment) : true
            && (filter.UniversityId.HasValue) ? s.UniversityId == filter.UniversityId : true
            && (filter.StudentStatusId.HasValue) ? s.StudentStatusId == filter.StudentStatusId : true
            && (filter.FacultyId.HasValue) ? s.FacultyId == filter.FacultyId : true
            && (filter.CityId.HasValue) ? s.CityId == filter.CityId : true
            && (!string.IsNullOrEmpty(filter.degree)) ? s.degree == filter.degree : true
            && (!string.IsNullOrEmpty(filter.degyear)) ? s.degyear == filter.degyear : true
            && (filter.NeighborhoodId.HasValue) ? s.NeighborhoodId == filter.NeighborhoodId : true
            && (filter.DealsCityId.HasValue) ? s.DealsCityId == filter.DealsCityId : true
            && (filter.FavoriteBusinessId.HasValue) ? s.Favorites.Any(f => f.BusinessId == filter.FavoriteBusinessId) : true
            && (s.StudentDeals.Count > 0)
            && (
                s.StudentDeals.Any(d =>
                    ((!string.IsNullOrEmpty(filter.DealsFrom)) ? d.UsedDateTime >= fromDate : true)
                    &&
                    ((!string.IsNullOrEmpty(filter.DealsTo)) ? d.UsedDateTime <= toDate : true)
                )
            )
            && (filter.DealsMin.HasValue) ? s.StudentDeals.Count >= filter.DealsMin : true
            && (filter.DealsMax.HasValue) ? s.StudentDeals.Count <= filter.DealsMax : true
            && (filter.CategoryId.HasValue) ? s.Categories.Any(c => c.Id == filter.CategoryId) : true
            && (filter.HasCardImage == true) ? s.CardImageFileName != null : true
            && (filter.HasCardImage == false) ? s.CardImageFileName == null : true
            && (filter.AppInstall == true) ? s.DeviceId != null : true
            && (filter.AppInstall == false) ? s.DeviceId == null : true
    ));
    return students.OrderBy(s => s.FirstName);
}

but its returend all the records... i entered fromdate and todate and i tried to entered DealsMin and DealsMax but same, returned all records.

what can i do ? tnx

edit:

i tried liked this:

private IQueryable<Student> FilterStudents(IQueryable<Student> students, StudentFilter filter)
{
    if (filter == null) return students; //No filter

    if (!string.IsNullOrEmpty(filter.FirstName))
    {
        students = students.Where(s => s.FirstName.Contains(filter.FirstName));
    }

    if (!string.IsNullOrEmpty(filter.LastName))
    {
        students = students.Where(s => s.LastName.Contains(filter.LastName));
    }

    if (!string.IsNullOrEmpty(filter.Email))
    {
        students = students.Where(s => s.Email.Contains(filter.Email));
    }

    if (!string.IsNullOrEmpty(filter.Phone))
    {
        students = students.Where(s => s.Phone.Contains(filter.Phone));
    }

    if (!string.IsNullOrEmpty(filter.Comment))
    {
        students = students.Where(s => s.Comment.Contains(filter.Comment));
    }

    if (filter.UniversityId.HasValue)
    {
        students = students.Where(s => s.UniversityId == filter.UniversityId);

    }

    if (filter.StudentStatusId.HasValue)
    {
        students = students.Where(s => s.StudentStatusId == filter.StudentStatusId);
    }

    if (filter.FacultyId.HasValue)
    {
        students = students.Where(s => s.FacultyId == filter.FacultyId);
    }

    if (filter.CityId.HasValue)
    {
        students = students.Where(s => s.CityId == filter.CityId);
    }

    if (!string.IsNullOrEmpty(filter.degree))
    {
        students = students.Where(s => s.degree == filter.degree);
    }

    if (!string.IsNullOrEmpty(filter.degyear))
    {
        students = students.Where(s => s.degyear == filter.degyear);
    }

    if (filter.NeighborhoodId.HasValue)
    {
        students = students.Where(s => s.NeighborhoodId == filter.NeighborhoodId);
    }

    if (filter.DealsCityId.HasValue)
    {
        students = students.Where(s => s.DealsCityId == filter.DealsCityId);
    }

    if (filter.FavoriteBusinessId.HasValue)
    {
        students = students.Where(s => s.Favorites.Any(f => f.BusinessId == filter.FavoriteBusinessId));
    }

    if (!string.IsNullOrEmpty(filter.DealsFrom))
    {
        var fromDate = DateTime.Parse(filter.DealsFrom);
        students = students.Where(s => s.StudentDeals.Any(d => d.UsedDateTime >= fromDate));
    }

    if (!string.IsNullOrEmpty(filter.DealsTo))
    {
        var toDate = DateTime.Parse(filter.DealsTo);
        students = students.Where(s => s.StudentDeals.Any(d => d.UsedDateTime <= toDate));
    }


    if (filter.DealsMin.HasValue)
    {
        students = students.Where(s => s.StudentDeals.Count >= filter.DealsMin);
    }

    if (filter.DealsMax.HasValue)
    {
        students = students.Where(s => s.StudentDeals.Count <= filter.DealsMax);
    }

    if (filter.CategoryId.HasValue)
    {
        students = students.Where(s => s.Categories.Any(c => c.Id == filter.CategoryId));
    }
    if (filter.HasCardImage == true)
    {
        students = students.Where(s => s.CardImageFileName != null);
    }
    if (filter.HasCardImage == false)
    {
        students = students.Where(s => s.CardImageFileName == null);
    }
    if (filter.AppInstall == true)
    {
        students = students.Where(s => s.DeviceId != null);
    }
    if (filter.AppInstall == false)
    {
        students = students.Where(s => s.DeviceId == null);
    }
    return students.OrderBy(s => s.FirstName);
}

but now when i entered filter.dealsMin and filter.dealsMax and toDate and FromDate its not doing AND between all params... its show only records after fromDate and ignored toDate...

I think is not a good idea filtering like you did. It's too messy and the query could be too heavy.

Try to do the query with if else blocks

if(!string.IsNullOrEmpty(filter.FirstName))
{
  students = students.Where(s => s.FirstName.Contains(filter.FirstName));
}

if(!string.IsNullOrEmpty(filter.LastName))
{
  students = students.Where(s => s.LastName.Contains(filter.LastName));
}

if(....)
{
...
}

I think is cleaner and you can get where you have the error easily

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM