Base solution for your next web application
Open Closed

Async Filtering against Database #3941


User avatar
0
carelearning created

Hello,

Currently we pull all information back and filter it to get single records like this:

(await  _userRepository.GetAllListAysnc()).FirstOrDefault(x => x.name == "Bob");

We would like to only pull back the information we need and write something like this:

_userRepository.GetAsync(x => x.name == "Bob")
or
_userRepository.GetAsync().Where(x => x.name == "Bob")

Is this possible? We see this project doing something similar: [https://github.com/zzzprojects/LINQ-Async])

Thank you for your time.


4 Answer(s)
  • User Avatar
    0
    aaron created
    Support Team

    Yes, this is possible:

    var bob = await _userRepository.FirstOrDefaultAsync(x => x.Name == "Bob");
    
  • User Avatar
    0
    carelearning created

    Hi Aaron,

    Thank you for your reply. My example was probably too simple. Your answer will indeed help in some places. A real example of our code is:

    var temporaryConflicts = (await _enrollmentRepository.GetAllListAsync())
                    .Where(x => x is Temporary)
                    .Where(x => !excludedIds.Contains(x.Id))
                    .GroupBy(x => x.Detail.Username)
                    .Where(g => g.Count() > 1)
                    .Select(g => g.Key);
    

    We would like something like this:

    var temporaryConflicts = _enrollmentRepository.GetAllListAsync()
                    .WhereAsync(x => x is Temporary)
                    .WhereAsync(x => !excludedIds.Contains(x.Id))
                    .GroupByAsync(x => x.Detail.Username)
                    .WhereAsync(g => g.Count() > 1)
                    .Select(g => g.Key);
    

    This way the filtering is done when the data is acquired (DB level) and not done afterwards (in memory).

    Thanks!

  • User Avatar
    0
    aaron created
    Support Team

    Use ToListAsync. Linq-to-SQL is compiled, so Where and GroupBy do not need async counterparts.

    var temporaryConflicts = await _enrollmentRepository.GetAll()
        .Where(x => x is Temporary)
        .Where(x => !excludedIds.Contains(x.Id))
        .GroupBy(x => x.Detail.Username)
        .Where(g => g.Count() > 1)
        .Select(g => g.Key)
        .ToListAsync();
    
  • User Avatar
    0
    carelearning created

    @Aaron

    Thank you.

    The

    .FirstOrDefaultAsync()
    

    and

    .GetAll()...ToListAsync()
    

    methods are exactly what we needed.

    And these changes should significantly speed up some of our methods.