I am kind of new to Entity Framework and ORMs. I have a simple database schema that is kind of like this.
User:
Id
Name
Group:
Id
Name
Role:
Id
Name
There are many-many between groups and users. Also, there is many-many between users and roles. However, Roles are per group. So we could have the following:
User A belongs to Group 1 with Roles a,b,c and belongs to Group 2, but has Roles d,e,f.
So we have some association tables like so:
UserRoles:
UserId -> User.Id
RoleId -> Role.Id
UserGroups
UserId -> User.Id
GroupId -> Group.Id
GroupRoles:
GroupId -> Group.Id
RoleId -> Role.Id
So, in my entities I want to have a Role entitiy, a User entity with a collection of Roles and a Group entity with a collection of Users and a collection of Roles.
When I load a group, I want to only load the users in that group and only that users roles for that group.
So my question:
In the above example. How do I make it so when I load Group 1, I want to see User A with Roles a,b,c and NOT Roles d,e,f.
Thanks,
JR
You need to call something like Group.User.Roles to get all Roles the user belongs to in the Group. something like:
var group1 = objectContext.Groups.Where(x => x.GroupId == 1);
var userARoles = group1.Users.Where(x => x.UserId == "A").Roles;
Does this help you?
Related
So i have a table with vehicles in my DB, each vehicle has a relationship with an user in the Users table and each user has a company value. I need to get all the vehicles that have a user that has an specific compay value.
example: query = vehicles.users(company = company)
If the relationship between vehicles and users is ManyToMany, and the relationship between company and user is OneToOne, you could do:
query = vehicles.objects.filter(user__company__id="my_company_id")
I am creating a tool where users can follow each other. The way I have Implemented this is by extending the user model in Django as people model.
here is the people Model ->
class People(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE,related_name='people')
Name = models.CharField(max_length=255,null=True)
following = models.ManyToManyField(to=User, related_name='following', blank=True)
photo = models.ImageField(upload_to='profile_pics', blank=True,null=True)
Phone_number = models.CharField(max_length=255,null=True,blank=True)
Birth_Date = models.DateField(null=True,blank=True)
Created_date = models.DateTimeField(auto_now_add=True)
Updated_date = models.DateTimeField(auto_now=True)
Here the poeple model is extended from user model and the relation is defined using oneToOneField.
Now the following column has many to many relation to the user model.
The Schema of the people_following table is that is has 3 columns
ID -> unique Identified (Primary Key)
People_id = user that has been followed.
User_id = user who is following(Logged in user)
suppose user with ID = 2 is logged in and wants to follow the User with ID = 7
then following will be the row in the table ->
ID people_id user_id
1 7 2
Now I would like to count the no of followers and the no of people following a particular user(Logged In user)
here is the Query ->
user_id = pk
person = People.objects.select_related('user').get(user_id=user_id)
context = {
'followers': person.following.filter(people_id=user_id).count(),
'following': person.following.filter(user_id = user_id).count(),
}
But this is giving me error ->
cannot resolve keyword -> people_id.
can anyone help me out with this.
I'm looking for a right solution for database structure regarding user permissions.
Tables:
users
companies (relevant columns: id)
projects (relevant columns: id,company_id)
jobs (relevant columns: id, company_id,project_id)
Scenarios I want to accomplish is to have specific user and/or users assigned to:
all the projects within company ("Cindy is assigned to all projects and all jobs within company")
select projects within company ("Cindy is assigned to three out of five projects and is assigned to all jobs within those three projects")
selected job(s) within project(s) ("Cindy is assigned to five jobs out of ten within one project and two jobs within the other project")
I think about separate permissions table where I just insert permissions to relevant jobs and to use the relevant columns from jobs table to cascade permissions upwards. In other words - if a user has permission for a specific job then it also has permission for parent project and parent company.
SQL Fiddle: http://sqlfiddle.com/#!9/74a4d3/2
Here is a proposed table structure for permissions:
USER_ID OBJ_TYPE OBJ_ID PERMISSION
JDOE COMPANY 1 1-READONLY
JDOE COMPANY 2 2-READWRITE
JDOE PROJECT 1 2-READWRITE
Then code to check user access could look something like:
SELECT MAX(permission) FROM permissions
WHERE user_id = :USERID
AND ( (obj_type = 'JOB' and obj_id = :JOBID)
OR (obj_type = 'PROJECT' and obj_id = :PROJECTID)
OR (obj_type = 'COMPANY' and obj_id = :COMPANYID))
I would like implement a database containing hierarchical acl data
My tables
USERS: idUser,username,...
GROUPS: idGroups,name...
GROUPSENTITIES: idGroup, idChild, childType (1 for users, 2 from groups)
ROLES : idRole,name...
ROLESENTITIES: idRole, IsDeny, idChild, childType (1 for users, 2 from groups)
Every user can belong to 0 or more groups
Every group can belong to 0 or more groups
Every user and every group can belong to 0 or more roles and roles can be allowed or denied
If an explicit deny is found, role is denied
How can I store this kind of data? Is my design correct?
Is it possible retrieve a list of users with all allowed roles?
Can you please write me a query (T-SQL based) for extract this information from db
thanks in advance
You can write the tables as you would expect. For instance, to get all the users in a group, when there are hierarchical groups, you would use a recursive CTE. Assume the group table is set up as:
create table groups (
groupid int,
member_userId int,
member_groupid int,
check (member_userId is NULL or member_groupid is null)
);
with usergroups as (
select groupid, member_userid, 1 as level
from groups
union all
select g.groupid, users.member_userid, 1+level
from users u join
groups g
on u.member_groupid = g.groupid
)
select *
from usergroups;
I am developing multitenant SaaS based application and going with Shared Database for storing all the tenant records with help of TenantId column.
Now the problem is i have some list of lookup records that needs to be shared for all the tenants. For example list of games.
GamesTable
Id
GameName
Also have another table used for storing only tenant specific records
TenantGames
Id
TenantId
GameName
The basic need is i want to use both table data and get the necessary details (Game_Name) while joining with another transaction table like UserGames. How can i achive this with this design? Here Game_Name can be either referred from Games Shared table or TenantSpecificGames table
Is there any other DB design which allows me to do mix both common master data and tenant master data with JOIN?
Basic requirement is keep common data and allow customization for the tenants if they want to add any new items.
This is the design I would then use.
Games
Id
GameName
IsTenantSpecific
SomeGameSpecificColumn
TenantGames
GameId
TenantId
SomeTenantSpecificColumn
AnotherTenantSpecificColumn
Then you can query that table in a Join with:
...
FROM
Games
INNER JOIN UserGames ON
UserGames.GameId = Games.Id
LEFT JOIN TenantGames ON
TenantGames.GameId = Games.Id
WHERE
TenantGames.TenantId = #tenantId OR
(
TenantGames.TenantId IS NULL AND
IsTenantSpecific = 0
)
Game specific fields can be put in the Games table. Tenant specific fields can be added to the TenantGames table, and those fields will be NULL if it is not a tenant specific customization.
We have a saas based database and we keep common data and tenant data in the same table.
Concept
GamesTable
Id NOT NULL
TenantId NULL
GameName NOT NULL
Add a unique key for TenantId and GameName
if TenantId is NULL you know it is common data
if TenantId is NOT NULL you know it belongs to a specific tenant and who exactly.
"Is there any other DB design which allows me to do mix both common
master data and tenant master data with JOIN?"
Yes
SELECT *
FROM GamesTable where TenantId = 'your tenant id'
UNION
SELECT *
FROM GamesTable where TenantId IS NULL -- common
This is a classic example of "many to many".
Table: Games
------------
GameID
GameName
IsMasterGame
TennantGames
------------------
GameID
TennantID
Tennants
------------
TennantID
...
To get the games for a given tennant, you would run a query like:
select *
from Games
where isMasterGame = true
union
select *
from Games g,
TennantGames tg
where g.GameID = tg.GameID
and isMasterGame = false
and tg.TennantID = $currentTennant
(Apologies for archaic join syntax)
The union allows you to ask two questions: which games apply to everyone (isMasterGame = true), and secondly which games apply to the current tennant (tg.TennantID = $currentTennant). Logically, tennant games cannot also be master games.
You can merge the tables leaving TenantId as NULL for records you wish to not be Tenant specific.
Games
Id
TenantId
GameName
The you can query that table in a Join with:
...
FROM
Games
INNER JOIN UserGames ON
UserGames.GameId = Games.Id
WHERE
Games.TenantId = #tenantId OR
Games.TenantId IS NULL
This will save you the trouble of ensuring that the Id is unique between the tables, unless you are using a UNIQUEIDENTIFIER for the Id.