Search code examples
c#linqsharp-repository

SharpRepository - Join Between Two Repositories


I have scoured the net and was unable to find any example of conducting a join between two SharpRepository repos. Can anyone provide a link to a page or an example? I am attempting to conver the following linq expression into a sharp repo expression:

        var user = (from f in _context.AccountUsers
                    join h in _context.Users on f.UserId equals h.UserId
                    where f.AccountId == accountId && h.UserName.Contains(email)
                    select new
                    {
                        h
                    });
        return (IEnumerable<User>)user;

----- UPDATE ------

This is what I came up with, but it doesn't seem to be working propertly...

            var aur = new AccountUserRepository();
        var user = this.Join(aur, u => u.UserName.Contains(email), au => au.AccountId == accountId, 
            (u, au)=> u).AsQueryable().AsEnumerable();
        return user;

Solution

  • There is a Join method on the repository that is similar to a LINQ Join statement and will let you join one IRepository<> with another IRepository<>. You pass it an IRepository<> to join with, an inner key selector, an outer key selector and a result selector.

    You can look here for an integration test that uses it: https://github.com/SharpRepository/SharpRepository/blob/master/SharpRepository.Tests.Integration/RepositoryJoinTests.cs

    The result of this call is another repository that you can then call GetAll, or FindAll, etc. on just like it was a normal IRepository<> itself. So I think you'll want to do something like this:

    var accountUserRepo = new AccountUserRepository();
    var userRepo = new UserRepository();
    
    // join on the UserId column that is common to both, and select an anonymous type with both pieces of info (you would select just what you need)
    var compositeRepo = accountUserRepo.Join(userRepo, au => au.UserId, u => u.UserId, (au, u) => new { AccountUserInfo = au, UserInfo = u } );
    
    return compositeRepo.FindAll(x => UserInfo.UserName.Contains(email) && x.AccountInfo.AccountId == accountId, x => x.UserInfo);
    

    That is how I think you would do it with the Join syntax.

    If you have navigation properties like you would in EF you could probably just do this syntax which is simpler:

    return accountUserRepo.FindAll(x => x.AccountId == accountId && x.User.UserName.Contains(email), x => x.User);