Linq Query relating Many to Many relationship - linq

i am trying to write a LINQ query but somehow it is not working, here is the query
var Table3Qry =
from LoginTable in db.Logins
from ServerTable in LoginTable.Servers.Where(x => x.ServerID == id)
select new { LoginTable.passwd, LoginTable.LoginID };
Table Structures are
Login
- Passwd
- Userid
- Loginid
Server
- Serverid
- Servername
ServerLogins
- Serverid
- Loginid
I want to find all the Passwords in Login table to a specific ServerID (named id in the query).

Filter servers by id, then select all passwords from each server logins:
var passwords =
db.Servers.Where(s => s.ServerID == id)
.SelectMany(s => s.Logins.Select(l => new { l.Passwd, l.LoginId }));
Query syntax:
var passwords = from s in db.Servers
where s.ServerID == id
from l in s.Logins
select new { l.Passwd, l.LoginId };
If you are starting from Logins table:
var passwords = from l in db.Logins
where l.Servers.Any(s => s.ServerID == id)
select new { l.Passwd, l.LoginId };

Related

we created okta_users, and okta_groups using terraform. but i am unable to get the specific user id, and group id

We created okta users, and okta groups using terraform
This is variables.tf
used variable list object for users and groups
variable "users" {
type = list(object
({
first_name = string
last_name = string
email = string
organization = string
role = string
okta_admin = bool
}))
}
variable "groups" {
type = list(object
({
name = string
description = string
}))
}
This is terraform.tfvars
groups = [
{ name = "dev", description = "This group for Devlopers" },
{ name = "qa", description = "This group for QA" },
{ name = "per", description = "This group for Per" }
]
users = [
{ first_name = "a", last_name = "a", email = "a#gmail.com", role = "Engineer", organization = "organization", okta_admin = true },
{ first_name = "b", last_name = "b", email = "b#gmail.com", role = "Lead", organization = "organization", okta_admin = true },
{ first_name = "c", last_name = "c", email = "c#gmail.com", role = "Devloper", organization = "organization", okta_admin = false },
]
this is main.tf
to get the values used for_each
resource "okta_group" "groups" {
for_each = { for group in var.groups : join("-", [group.name, group.description]) => group }
name = each.value.name
description = each.value.description
}
resource "okta_user" "okta_user_add" {
for_each = { for user in var.users : join("-", [user.first_name, user.last_name]) => user }
title = each.value.role
email = each.value.email
first_name = each.value.first_name
last_name = each.value.last_name
login = each.value.email
organization = each.value.organization
}
when we are trying to get id we tried multiple things but it didn't work for us.
unable to get the group id and user id's
resource "okta_group_memberships" "okta_member_group" {
for_each = okta_group.groups
group_id = each.value.id # I want only select one group
users = users = values(okta_user.okta_user_add)[*].id
}
my question is
okta_group_memberships.okta_member_group
we have multiple groups but we need only one group to add in okta_group_memberships.
and we also to add specific user. I mention in tfvars file. there users object we have okta_admin = true. we need only those users we need in the okta_member_group
For retrieving all the group id, you could iterate over the okta_user resources:
resource "okta_group_memberships" "okta_member_group" {
group_id = each.value.id
# Add all users to each group
users = values(okta_user.okta_user_add)[*].id
}
The problem with your question is that you don't specify anywhere which user belongs to which group, so I've used a splat expression to get all the ids of all the users.
You should create a separate input variable in order to map each user to certain group.
Edit:
locals {
# get DEV group
dev_group = [for group in var.groups: group if group.name == "dev"][0]
# filter okta admins
okta_admins = [for user in var.users: join("-", [user.first_name, user.last_name]) if user.okta_admin]
}
resource "okta_group_memberships" "okta_member_group" {
# select only the DEV group
group_id = okta_group.groups[join("-", [local.dev_group.name, local.dev_group.description])].id
# get IDs of okta_admins only
users = [for okta_admin in local.okta_admins: okta_user.okta_user_add[okta_admin].id]
}

Create complex argument-driven queries from AWS Lambda?

Look for // HERE IS THE PROBLEM PART sentence to find code that is the problem.
I am trying to implement AppSync using AWS Lambda (that connects to RDS Postgres server) as a data source. I want to create puKnowledgeFile query that will update my KnowledgeFile with optional arguments. If the client only provided htmlText and properties as arguments, then my update query should only update these two fields.
type Mutation {
putKnowledgeFile(
id: ID!,
htmlText: String,
plainText: String,
properties: AWSJSON
): KnowledgeFile
}
type KnowledgeFile {
id: ID!
htmlText: String!
plainText: String!
properties: AWSJSON!
lastDateTimeModified: AWSDateTime!
dateTimeCreated: AWSDateTime!
}
Here is an piece of AWS Lambda code:
exports.handler = async (event, context, callback) => {
/* Connecting to Postgres */
let data = null;
let query = ``;
let values = [];
switch (event.info.fieldName) {
case "putKnowledgeFile":
if(event.arguments.htmlText === undefined &&
event.arguments.plainText === undefined &&
event.arguments.properties === undefined) {
callback(`At least one argument except id should be provided in putKnowledgeFile request`);
}
// HERE IS THE PROBLEM PART
query += `update knowledge_file`
query += `
set `;
let index = 0;
for (let fieldName in event.arguments) {
if(arguments.hasOwnProperty(fieldName)) {
const fieldValue = event.arguments[fieldName];
if(index === 0) {
query += `${fieldName}=$${index+1}`
values.push(fieldValue);
} else {
query += `, ${fieldName}=$${index+1}`
values.push(fieldValue);
}
index++;
}
}
query += `
where knowledge_file.id = $${index+1};`;
values.push(event.arguments.id);
// HERE IS THE PROBLEM PART
break;
default:
callback(`There is no functionality to process this field: ${event.info.fieldName}`);
return;
}
let res = null;
try {
res = await client.query(query, values); // just sending created query
} catch(error) {
console.log("#client.query");
console.log(error);
}
/* DisConnecting from Postgres */
callback(null, res.rows);
};
Basically, this algorithm creates my query string through multiple string concatenations. I think it's too complicated and error-prone. Is there a way to create dynamic queries based on the presence / absence of certain arguments easily?
Just in case, here is my PostgreSQL schema:
-- main client object for clients
CREATE TABLE client (
id bigserial primary key,
full_name varchar(255)
);
-- knowledge_file
create table knowledge_file (
id bigserial primary key,
html_text text,
plain_text text,
properties jsonb,
last_date_modified timestamptz,
date_created timestamptz,
word_count varchar(50)
);
-- which client holds which knowledge file
create TABLE client_knowledge_file (
id bigserial primary key,
client_id bigint not null references client(id),
knowledge_file_id bigint not null references knowledge_file(id) unique ON DELETE CASCADE
);
I know this is not an optimum solution and might not completely answer your question but I also ran into similar problem and this is how I solved it.
I created a resolver pipeline.
In one function, I used the select statement to get the current
record.
In second function, I checked if the fields (in your case htmlText and properties) are null. If true, then use the ctx.prev.result values otherwise use the new ones).
Practical example
First resolver function:
{
"version": "2018-05-29",
"statements": [
"select id, html_text AS \"htmlText\", plain_text AS \"plainText\", properties, last_date_modified AS \"lastDateTimeModified\", date_created AS \"dateTimeCreated\" from knowledge_file where id = $ctx.args.Id"
]
}
Second resolver function:
#set($htmlText = $util.defaultIfNull($ctx.args.htmlText , $ctx.prev.result.htmlText))
#set($properties = $util.defaultIfNull($ctx.args.properties , $ctx.prev.result.properties))
{
"version": "2018-05-29",
"statements": [
"update knowledge_file set html_text = $htmlText, plain_text = $ctx.args.plainText, properties = $properties, last_date_modified = CURRENT_TIMESTAMP, date_created = CURRENT_DATE where id = $ctx.args.Id returning id, html_text AS \"htmlText\", plain_text AS \"plainText\", properties, last_date_modified AS \"lastDateTimeModified\", date_created AS \"dateTimeCreated\""
]
}

Find where results in columns from an array of column names in TypeORM

At the moment I have the following query:
return await this.siteRepository.find({
where: [{ id: Like(`%${q}%`) }, { name: Like(`%${q}%`) }]
});
But I would like to be able to pass a list of column names to be used for the query from an array and not write each one of them manually.
const columns = ["id","name", "lastName", "age"]
const query = {};
return await this.siteRepository.find({
where: columns.map(column=>{(query[`${column}`] = `Like("%${q}%")}`)})
});
Is this even possible? I'm starting to feel like it currently is not.
I didn't manage to accomplish what I wanted with the Repository TypeORM methods but I did manage to do it with the QueryBuilder
Here is my solution
const res = ['id', 'name'].map(item => `${item} LIKE :q`).join(' OR ');
return await this.siteRepository
.createQueryBuilder()
.where(res, { q: `%${q}%` })
.getMany();
Which yields a query of
SELECT `User`.`id` AS `User_id`, `User`.`name` AS `User_name`, `User`.`lastName` AS `User_lastName`, `User`.`active` AS `User_active` FROM `user` `User` WHERE name LIKE ? OR id LIKE ?

how to improve linq-to-sql query

I am executing the following query in LINQPad:
Tickets.GroupJoin(UserRoles, t => t.AuthorId, r => r.UserId, (ticket, roles) => new {
AuthorId = ticket.AuthorId,
AuthorRoles = roles.Select(r => r.Role).Distinct(),
Message = ticket.Message,
Replies = ticket.TicketReplies.GroupJoin(UserRoles, reply => reply.AuthorId, role => role.UserId, (reply, roles2) => new {
AuthorId = reply.AuthorId,
AuthorRoles = roles2.Select(r => r.Role).Distinct(),
Message = reply.Message
})
}).Take(1000)
Where AuthorId is a string, AuthorRoles a list of ints, and Message a string. This query performs terribly. This query results in an excess of 2000 queries being sent from LINQPad.
Why is LINQPad unable to translate this into a single SQL query?
Can I formulate my query differently so that LINQPad is able to perform better?

LINQ Lambda Join Error - cannot be inferred from the usage

I had troubles joining two DbSets and continued to receive the "cannot be inferred error". I struggled to find a solution so I thought I would share my simple answer. There are several great posts from Jon Skeet and others but most of the answers were over my head.
Here is the code that was causing me trouble:
using(var db = new SomeDataContext())
{
db.DemandData
.Where(demand=> demand.ID == SearchID)
.Join(db.CUST_ORDER_LINE,
supply=> new { supply.LINE, supply.SALES_ORDER_ID },
demand=> new { demand.LINE_NO, demand.CUST_ORDER_ID },
(supply, demand) => new { custOrderLineReturn = demand })
.Select(s => s.custOrderLineReturn )
.ToList();
}
I have done this join so many times that I could not figure out why it would not work until I found a post from Justin Niessner here that says "The names of the properties in the anonymous types (as well as their types) must match exactly." That lead me to this code:
using(var db = new SomeDataContext())
{
return db.DemandData
.Where(demand=> demand.ID == SearchID)
.Join(db.CUST_ORDER_LINE,
supply=> new { LINE_NO = supply.LINE, CUST_ORDER_ID = supply.SALES_ORDER_ID },
demand=> new { demand.LINE_NO, demand.CUST_ORDER_ID },
(supply, demand) => new { custOrderLineReturn = demand })
.Select(s => s.custOrderLineReturn )
.ToList();
}
In the sixth line I added variables LINE_NO = and CUST_ORDER_ID = that matched the field names in line seven.

Resources