I'm developing a system with some complex logic regarding user permissions to access different data from a SQL Server database using C#
and Entity Framework
. I have different places across the system where I need to query certain DB entities called 'documents' that are only accessible to current user. I came up with the following class that queries only the necessary documents:
internal class DocumentPermissionsHelper
{
private readonly MyDbContext dc;
public DocumentPermissionsHelper(MyDbContext dc) { this.dc = dc; }
public IQueryable<Document> SelectDocumentsAccessibleToUser(IQueryable<Document> query, Guid userId)
{
var permissionsQuery = dc. ... // really big query with multiple JOIN's to determine which user has access to which documents
IQueriable<Guid> docIdsAccessibleToUserQuery =
from permissions in permissionsQuery.Where(_ => _.UserId == userId && _.AccessLevel == "Read")
select permissions.DocumentId;
return from accessibleDocId in docIdsAccessibleToUserQuery.Distinct()
from accessibleDoc in query.Where(g => g.Id == accessibleDocId)
select accessibleDoc;
}
}
Then I use it in several different queries like this:
public void GetLatestDocsCount(Guid currentUserId)
{
using (var dc = new MyDbContext(_environment))
{
var helper = new DocumentPermissionsHelper(dc);
var docQuery = dc.Docs.Where(d => d.CreatedDate > DateTime.Now.AddDays(-1));
docQuery = helper.SelectDocumentsAccessibleToUser(docQuery, currentUserId);
int latestDocsCount = docQuery.Count();
return latestDocsCount;
}
}
As I said, I have many different queries that produce different kinds of data, but all have one common part: the building of subquery that selects only documents accessible to a certain UserID.
Is there a better way to 'inject' this common query part into multiple Entity Framework
queries rather than instantiate DocumentPermissionsHelper
every time? My own solution seems somewhat clumsy to me.