I am using 3 tables to set roles for users.
1. module
Id, Name
2. actions
Id , Name ,ModuleId (Foreign key with modules)
3. userActions
Id,UserId,ActionId (Foreign key with actions)
I want to get the unique list of modules for a user from the userActions table . I am using Entity Framework and my database is Mysql
I used the query
var result = (from p in my_accountEntities.useractions
where p.UserId == item.Id
select p.action.module).ToList();
List<module> modules = new List<module>();
if (result != null)
{
modules = (List<module>)result;
}
Its not returning a Unique list , but its returning all the rows in Useraction table.
How can i get the unique list of modules(based on moduleId)
try using the linq .Distinct() extension method
var result = (from p in my_accountEntities.useractions
where p.UserId == item.Id
select p.action.module)
.Distinct().ToList();
Related
I am working with a legacy MySQL database in Kotlin using the Exposed library. I've got it working fine with MySQL (simple queries work as expected). I'm running MySQL version 5.7.26, but I don't think the problem is related to MySQL itself.
I have two tables, events and event_years. The relevant columns in events are the id (int, primary key), and name (varchar 255). Event_years contains an id (int, primary key), year (datetime), and event_id (int, foreign key), among other things that are not relevant to this question.
An event may have zero or more rows in event_years referring to it. I would like to select the event name, and year, and order the results by year.
I was able to achieve this using the mysql CLI like this:
SELECT e.id, e.name, y.id, y.date
FROM events e, event_years y
WHERE e.id = y.event_id
ORDER BY y.date;
In Kotlin, I have created objects for Events and EventYears:
object Events : Table("events") {
val id = integer("id").autoIncrement().primaryKey()
val name = varchar("name", length = 255)
}
object EventYears : Table("event_years") {
val id = integer("id").autoIncrement().primaryKey()
val eventId = integer("event_id").uniqueIndex()
val date = date("date")
}
I have then tried the following query:
val res = EventYears.innerJoin(Events)
.slice(Events.name, Events.id, EventYears.date, EventYears.id)
.select { EventYears.eventId eq Events.id }
.groupBy(EventYears.date)
I expected the result to be an Iterable object containing these values (like the ones I've received when doing queries without joining), but an exception was raised:
java.lang.IllegalStateException: Cannot join with foo.bar.Events#b307e119 as there is no matching primary key/ foreign key pair and constraint missing
Thank you in advance for any help. I've read the Exposed documentation twice now and still can not understand why this is not working.
You should define your eventId as val eventId = reference("film", Events).uniqueIndex() then you'll be possible to use your query without an exception.
The other way is to provide both columns explicitly in innerJoin
val res = EventYears.innerJoin(Events, {EventYears.eventId}, {Events.id})
.slice(Events.name, Events.id, EventYears.date, EventYears.id)
.selectAll()
.groupBy(EventYears.date)
Try specifying the constraint :
val joinResult = Events.join(EventYears, JoinType.INNER, additionalConstraint = {
EventYears.eventId eq Events.id
Then select as follows
joinResult.select({ EventYears.eventId eq Events.id }) {
val eventId = it[Events.id]
val eventYearsId = it[EventYears.eventId]
}
I have a query like :
$qb = $this->createQueryBuilder('m');
$qb->select('m.id', 'IDENTITY(m.home)');
return $qb->getQuery()->getResult();
m.home field is a foreign key to another table (This other table has a field ID and another name).
With this I get Id of m and id of the foreign key.
How can I get the name field of my other instead of id ?
You can fetch the data of the associated entity with a join:
SELECT m.id, home.name
FROM YourEntity AS m
JOIN m.home AS home
Use a leftJoin to get data from a relationship:
$qb = $this->createQueryBuilder('m');
$qb = $qb->leftJoin('AppBundle\Entity\Home', 'h');
$qb->select('m.id', 'IDENTITY(m.home)', 'h.name');
return $qb->getQuery()->getResult();
Replace 'AppBundle\Entity\Home' by the namespaced class of your entity "home".
We have a table of data that looks like:
CREATE TABLE objects (
id BIGSERIAL NOT NULL,
typeid BIGINT NOT NULL,
fullobject JSON,
PRIMARY KEY (id),
...
);
and
CREATE TABLE types (
id BIGSERIAL NOT NULL,
type VARCHAR(255),
PRIMARY KEY (id),
...
);
in the objects.fullobject column is JSON data for users and orgs like:
// id: 1
{
...
"type":"1", // user
"orgs":[
{"id":"2", "position":"foo"},
{"id":"2", "position":"bar"},
{"id":"3", "position":"foo"},
]
}
// id: 2
{
...
"type":"2", // org
"name":"Org 1"
}
// id: 3
{
...
"type":"2", // org
"name":"Org 2"
}
The question is, if I want to find a user based on the name of the organisation, how do I do the join?
I'm not sure if I can create the right index on the org data inside a user.
The two solutions I can think of are:
Create a single text attribute that contains the id's of the orgs for a user, then do a join based of that (e.g. "searchableOrg": "|org1|org2|").
Then the query looks like:
SELECT * from objects user
INNER JOIN types usertype ON usertype.id = user.typeid
INNER JOIN objects org ON json_extract_path(user.fullobject, 'searchableOrg') LIKE '%|' || org.id || '|%'
INNER JOIN types usertype ON usertype.id = user.typeid
WHERE json_extract_path(org.fullobject, 'name') LIKE '%whatever%'
AND usertype.type = 'user'
AND orgtype.type = 'org'
Here I can have indexes on json_extract_path(user.fullobject, 'searchableOrg') and json_extract_path(org.fullobject, 'name').
However this doesn't work if we add things like a start or end date to the user's organisation membership and need to further filter the join on that.
Create a trigger that when a user is created/update/deleted modifies a table (userorgtable) that contains the user org membership and do the join off of that.
I haven't looked at triggers yet, but hopefully the query would be something like:
SELECT * from objects user
INNER JOIN userorgtable userorg ON user.id = userorg.userid
INNER JOIN types usertype ON usertype.id = user.typeid
INNER JOIN objects org ON userorg.orgid = org.id
INNER JOIN types orgtype ON orgtype.id = org.typeid
WHERE json_extract_path(org.fullobject, 'name') LIKE '%whatever%'
AND usertype.type = 'user'
AND orgtype.type = 'org'
In this case, if we needed to add further attributes to the join (such as start and end dates), we can just put them in the userorgtable and have add conditions like:
AND userorg.startdate < CURRENT_DATE()
Is there another option? Perhaps using more of the Postgres JSON functions?
Thanks in advance
I have the following table strutucture and am accessing them by using MySQL Entity Framework:
Table Users
- Id
- Name
Table Subscriptions
- Id
- Id_User
- Id_Course
Table Courses
- Id
- Name
What I would like and am having a hard time to do so is building a link query for all users that returns a list with each entry containing:
User Id;
User name;
Concat string separated by comma with all courses for the user or 'no courses' string if none.
This list should be filtered by a part of users name.
I've started to build the code but can't finish it:
var Model db = new Model();
var list = from user in db.Users
join ???
where user.Name.Contains(filter.Trim())
select new { Name = user.Name, Id = user.Id, ???}
Can anyone help me please ?
You should use navigation properties (like User.Subscriptions) for this. Depending on how you created the model they may already be there, else you first should add them.
var query = from u in db.Users
where user.Name.Contains(filter) // trim the filter value first
select new
{
u.Name,
u.Id,
Courses = u.Subscriptions.Select(s => s.Course.Name)
};
var result = query.AsEnumerable()
.Select(q => new
{
q.Name,
q.Id
Courses = string.Join(", ", q.Courses)
};
The reason for doing this in two phases is that string.Join can't directly be used in an EF LINQ expression (can't be turned into SQL) so it must be done in memory (i.e. after an AsEnumerable).
But still it may be efficient to do a projection first (the first part), otherwise too much data may be fetched from the database.
I currently have two separate SQL JOINS. One is getting a project name and the other a class name from two different tables from the same ID.
A table called PUPILPROJECT holds an ID, projectID and ClassID which are also in a PROJECT table with the PROJECT name and a CLASS table with the CLASS name.
Is there a way of doing this with a single query? All help is much appreciated!
//GET PROJECT NAME
$getproject = mysql_query("SELECT project_name FROM projects JOIN pupilproject USING (project_id) WHERE pupil_project_id = '".$id."'");
while ($row = mysql_fetch_array($getproject)) {
$thisproject = $row['project_name'];
}
//GET PROJECT CLASS NAME
$classname = mysql_query("SELECT class_name FROM class JOIN pupilproject USING (class_id) WHERE pupil_project_id = '".$id."'");
while ($row = mysql_fetch_array($classname)) {
$pclass = $row['class_name'];
}
Use the following SQL in your code:
"SELECT project_name, class_name
FROM pupilproject
LEFT JOIN projects USING (project_id)
LEFT JOIN class USING (class_id)
WHERE pupil_project_id = '".$id."'"