简体   繁体   中英

Entity Framework complex multiple where condition

I have a database in which I'm trying to track document approvals. Each document has 1 or more tasks. Each task has 1 or more approvals. Each approval has the ID to the assigned user as well as an assigned group. Each user may belong to 1 or more groups and may have various permissions in each group. This information is stored in a 'many to many' relationship table with an additional field for permissions level. (user_id, group_id, permission_id)

For example, an approval to a task may be assigned to a user with ID=5 and to a group with ID=7. In order for a user to approve this approval, they either must have a user ID of 5 or belong to group 7 with the permission to approve.

I'd like to create a query which selects all approvals either assigned to a particular user or belong to a group that a particular user have 'awareness' permissions to.

I have easily been able to query for just the user ID with:

var approvals = context.APPROVALS
                       .Where(a => a.APPROVER_ID == CurrentUserID)
                       .ToList();

My issue is also checking against the groups that the current user has 'awareness' permissions to. The best I have been able to come up with is storing a list of the users 'awareness' groups (stored as CurrentUserAwarnessGroups in the example below) and doing something like the following:

var approvals = context.APPROVALS
                       .Where(a => a.APPROVER_ID == CurrentUserID || CurrentUserAwarnessGroups.Contains(a.GROUP_ID))

This query method fails for me not to mention I am assuming it must perform at least part of this query on the client side which means a much larger (and lengthier) query is returned.

Can anyone suggest a better way to perform this functionality? I can change my database if necessary.

So I was able to figure out a better method. My approach was incorrect. Rather than trying to query approvals and include the related user, I queried by user and included related approvals purely based on their group. I determined the approval group will always contain the approver ID therefore I can query the database by group alone and then filter by approver on the client machine. Additionally, by using bitwise comparisons to control 'membership' as recommended by mxmissile, I am able to simplify my group-to-user table.

My solution looks like:

var user = context.USERs
                  .Where(u => u.USER_ID == CurrentUserID)
                  .FirstOrDefault();

var tempUserApprovals = user.GROUPTOUSER.SelectMany("GROUP.APPROVALS");
var userApprovals = new ObservableCollection<APPROVAL>();

foreach(var approval in tempUserApprovals)
{
    foreach(var group in CurrentUsersGroups)
    {
        if(approval.GROUP.GROUP_ID == group.GROUP_ID && ((int)group.MEMBERSHIP & Membership.is_aware == Membership.is_aware || approval.APPROVER_ID == CurrentUserID))
        {
            userApprovals.Add(approval);
        }
    }
}

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