I have 2 Models, and I want it to show the Name of the Faculty instead of the ID shown below.
enter image description here
I am displaying the User's own Article that has submitted it.
How can I change an ID to a Name Faculty that contains that ID?
Edit your repository by including the foreign key columns like this
public IEnumerable<Article> GetPersonalArticles(string userName)
{
return _dbContext.Articles.Include(a=>a.Faculty).Where(a => a.Author == userName).ToList();
}
Related
Here are three tables
Table users {
id uuid [pk, default: `gen_random_uuid()`]
auth_id uuid [ref: - auths.id]
org_id uuid [ref: - orgs.id]
access_group text [default: 'DEFAULT']
created_at int [default: `now()::int`]
updated_at int
age int
status text
}
Table op_user_access_groups {
op_id uuid [pk, ref: > ops.id]
access_group text [pk, default: 'DEFAULT']
}
Table op_users {
op_id uuid [pk, ref: > ops.id]
user_id uuid [pk, ref: > users.id]
access boolean [default: false]
}
The table users has user info and he/she belongs to certain organization (org_id)
The table op_user_access_groups has the information regarding an operator having access to what all access_groups. The op_id belongs to the org_id
The table op_users has information about users (user_id) that can be accessed by op_id irrespective of which group a user belongs to.
I want to create a view such that if I do
select * from <that view> where op_id = ?
I should get the users the operator has access to.
Any help is appreciated :)
You should use a JOIN query to create such a view. Something like this:
CREATE VIEW v AS
SELECT * FROM users
JOIN op_users ON users.id=op_users.op_id
JOIN op_user_access_groups ON op_user_access_groups.access_group=users.access_group
WHERE op_users.access = true
It's not exactly clear how your data model works from your question, but creating a view with the JOIN that answers your question is the correct response here.
I have three tables. I want to display all data from cms_planner table together with Topic Name from cms_topic table. To achieve that, I need to go through the cms_subject table.
I want to use belongsToMany but I already have cms_subject table that holds the foreign key for cms_planner and the foreign key for cms_topic. The table name does not represent pivot key.
I also want to use hasManyThrough but it doesn't work. I'm thinking to inverse the hasManyThrough.
How can I achieve that?
1. CmsPlanner
i. planner_id
ii. subject_id
iii. date_start
2. CmsSubject
i. subject_id
ii. topic_id
3. CmsTopic
i. topic_id
ii. topic name
In CmsPlanner model
public function subject(){
return $this->hasManyThrough(
'App\CmsTopic',
'App\CmsSubject',
'topic_id', 'topic_id', 'planner_id');}
In CmsPlanner controller
CmsPlanner::with('subject')->get();
Add this relation on CmsSubject
public function cmsTopic()
{
return $this->belongsTo('App\Models\CmsTopic', 'topic_id', 'topic_id');
}
then add following relation on CmsPlanner
public function cmsSubject()
{
return $this->belongsTo('App\Models\CmsSubject', 'subject_id', 'subject_id');
}
to get data
$cms_planner = CmsPlanner::with('CmsSubject')->where('id', $planner_id)->get();
'user' => $this->business->user
I know I can't return multiple values with the Case statement but this is the best way I can explain what I want to accomplish. I am trying to write a statement where I will return different values based on what is entered in another field. I have something like this currently:
SELECT animal WHERE
CASE
WHEN :textbox is not null
THEN (SELECT animal from animalsTable where animalType = :textbox
ELSE (SELECT plant from plantsTable where plantType = 'edible')
So basically, I want to be able to list all the animals that correspond to what the user types in the textbox, but if they do not enter anything in the textbox, then I want to show them all plants that are edible instead. I almost always going to return multiple values for each value they enter.
For example, if the user types 'dog' then i will return 'dog' and 'wolf'. So this causes a problem since the case statement is boolean. How can I get around this?
Thanks.
You can create an ALN Domain that contains all your lookup value list. In this case, both animals and plants. Then create a table domain that references ALN domain based on the key field you want to filter by. You'll need store this key in the Description field as a single value, or multiple values separated by a space or comma.
For us, we used a custom field (subcategory) that displayed a limited lookup from the ALN Domain using a Table domain filtering on the asset department number. The Asset Department Number is listed in the ALN Domain description.
ALN domain contains your plant and animal values. Description of ALN domain contains your key field vale.
If the Asset Department is empty, then entire list shows up.
The list where clause looks something like this:
domainid='CBRSUBCAT' and description like '%' || (select eq5 from asset where assetnum = :assetnum) || '%'
I used a like so we could enter multiple departments for one subcategory separated by comma. For you, you could use description = (equals) if you wanted.
You could check the textbox value for each table and union the results:
select animal from animalsTable where animalType = :textbox
and :textbox is not null
union all
select plant from plantsTable where plantType = 'edible'
and :textbox is null
I have my database structure like this ::
Database structure ::
ATT_table- ActID(PK), assignedtoID(FK), assignedbyID(FK), Env_ID(FK), Product_ID(FK), project_ID(FK), Status
Product_table - Product_ID(PK), Product_name
Project_Table- Project_ID(PK), Project_Name
Environment_Table- Env_ID(PK), Env_Name
Employee_Table- Employee_ID(PK), Name
Employee_Product_projectMapping_Table -Emp_ID(FK), Project_ID(FK), Product_ID(FK)
Product_EnvMapping_Table - Product_ID(FK), Env_ID(FK)
I want to insert values in ATT_Table. Now in that table I have some columns like assignedtoID, assignedbyID, envID, ProductID, project_ID which are FK in this table but primary key in other tables they are simply numbers).
Now when I am inputting data from the user I am taking that in form of string like a user enters Name (Employee_Table), product_Name (Product_table) and not ID directly. So I want to first let the user enter the name (of Employee or product or Project or Env) and then value of its primary key (Emp_ID, product_ID, project_ID, Env_ID) are picked up and then they are inserted into ATT_table in place of assignedtoID, assignedbyID, envID, ProductID, project_ID.
Please note that assignedtoID, assignedbyID are referenced from Emp_ID in Employee_Table.
How to do this ? I have got something like this but its not working ::
INSERT INTO ATT_TABLE(Assigned_To_ID,Assigned_By_ID,Env_ID,Product_ID,Project_ID)
VALUES (A, B, Env_Table.Env_ID, Product_Table.Product_ID, Project_Table.Project_ID)
SELECT Employee_Table.Emp_ID AS A,Employee_Table.Emp_ID AS B, Env_Table.Env_ID, Project_Table.Project_ID, Product_Table.Product_ID
FROM Employee_Table, Env_Table, Product_Table, Project_Table
WHERE Employee_Table.F_Name= "Shantanu" or Employee_Table.F_Name= "Kapil" or Env_Table.Env_Name= "SAT11A" or Product_Table.Product_Name = "ABC" or Project_Table.Project_Name = "Project1";
The way this is handled is by using drop down select lists. The list consists of (at least) two columns: one holds the Id's teh database works with, the other(s) store the strings the user sees. Like
1, "CA", "Canada"
2, "USA", 'United States"
...
The user sees
CA | Canada
USA| United States
...
The value that gets stored in the database is 1, 2, ... whatever row the user selected.
You can never rely on the exact, correct input of users. Sooner or later they will make typo's.
I extend my answer, based on your remark.
The problem with the given solution (get the Id's from the parent tables by JOINing all those parent tables together by the entered text and combining those with a number of AND's) is that as soon as one given parameter has a typo, you will get not a single record back. Imagine the consequences when the real F_name of the employee is "Shant*anu*" and the user entered "Shant*aun*".
The best way to cope with this is to get those Id's one by one from the parent tables. Suppose some FK's have a NOT NULL constraint. You can check if the F_name is filled in and inform the user when he didn't fill that field. Suppose the user eneterd "Shant*aun*" as name, the program will not warn the user, as something is filled in. But that is not the check the database will do, because the NOT NULL constraints are defined on the Id's (FK). When you get the Id's one by one from the parent tables. You can verify if they are NOT NULL or not. When the text is filled in, like "Shant*aun*", but the returned Id is NULL, you can inform the user of a problem and let him correct his input: "No employee by the name 'Shantaun' could be found."
SELECT $Emp_ID_A = Emp_ID
FROM Employee_Table
WHERE F_Name= "Shantanu"
SELECT $Emp_ID_B = Emp_ID
FROM Employee_Table
WHERE B.F_Name= "Kapil"
SELECT $Env_ID = Env_ID
FROM Env_Table
WHERE Env_Table.Env_Name= "SAT11A"
SELECT $Product_ID = Product_ID
FROM Product_Table
WHERE Product_Table.Product_Name = "ABC"
SELECT $Project_ID = Project_ID
FROM Project_Table
WHERE Project_Name = "Project1"
Please use AND instead of OR.
INSERT INTO ATT_TABLE(Assigned_To_ID,Assigned_By_ID,Env_ID,Product_ID,Project_ID)
SELECT A.Emp_ID, B.Emp_ID, Env_Table.Env_ID, Project_Table.Project_ID, Product_Table.Product_ID
FROM Employee_Table A, Employee_Table B, Env_Table, Product_Table, Project_Table
WHERE A.F_Name= "Shantanu"
AND B.F_Name= "Kapil"
AND Env_Table.Env_Name= "SAT11A"
AND Product_Table.Product_Name = "ABC"
AND Project_Table.Project_Name = "Project1";
But it is best practice to use drop down list in your scenario, i guess.
I have an entity called Books that can have a list of more books called RelatedBooks.
The abbreviated Book entity looks something likes this:
public class Book
{
public virtual long Id { get; private set; }
public virtual IList<Book> RelatedBooks { get; set; }
}
Here is what the mapping looks like for this relationship
HasManyToMany(x => x.RelatedBooks)
.ParentKeyColumn("BookId")
.ChildKeyColumn("RelatedBookId")
.Table("RelatedBooks")
.Cascade.SaveUpdate();
Here is a sample of the data that is then generated in the RelatedBooks table:
BookId RelatedBookId
1 2
1 3
The problem happens when I Try to delete a book. If I delete the book that has an ID of 1, everything works ok and the RelatedBooks table has the two corresponding records removed. However if I try to delete the book with an ID of 3, I get the error "The DELETE statement conflicted with the REFERENCE constraint "FK5B54405174BAB605". The conflict occurred in database "Test", table "dbo.RelatedBooks", column 'RelatedBookId'".
Basically what is happening is the Book cannot be deleted because the record in the RelatedBooks table that has a RelatedBookId of 3 is never deleted.
How do I get that record to be deleted when I delete a book?
EDIT
After changing the Cascade from SaveUpdate() to All(), the same problem still exists if I try to delete the Book with an ID of 3. Also with Cascade set to All(), if delete the Book with and ID of 1, then all 3 books (ID's: 1, 2 and 3) are deleted so that won't work either.
Looking at the SQL that is executed when the Book.Delete() method is called when I delete the Book with an ID of 3, it looks like the SELECT statement is looking at the wrong column (which I assume means that the SQL DELETE statment would make the same mistake, therefore never removing that record). Here is the SQL for the RelatedBook
SELECT relatedboo0_.BookId as BookId3_
, relatedboo0_.RelatedBookId as RelatedB2_3_
, book1_.Id as Id14_0_
FROM RelatedBooks relatedboo0_
left outer join [Book] book1_ on relatedboo0_.RelatedBookId=book1_.Id
WHERE relatedboo0_.BookId=3
The WHERE statment should look something like this for thie particular case:
WHERE relatedboo0_.RelatedBookId = 3
SOLUTION
Here is what I had to do to get it working for all cases
Mapping:
HasManyToMany(x => x.RelatedBooks)
.ParentKeyColumn("BookId")
.ChildKeyColumn("RelatedBookId")
.Table("RelatedBooks");
Code:
var book = currentSession.Get<Book>(bookId);
if (book != null)
{
//Remove all of the Related Books
book.RelatedBooks.Clear();
//Get all other books that have this book as a related book
var booksWithRelated = currentSession.CreateCriteria<Book>()
.CreateAlias("RelatedBooks", "br")
.Add(Restrictions.Eq("br.Id", book.Id))
.List<Book>();
//Remove this book as a Related Book for all other Books
foreach (var tempBook in booksWithRelated)
{
tempBook.RelatedBooks.Remove(book);
tempBook.Save();
}
//Delete the book
book.Delete();
}
Rather than setting the cascade attribute, I think you need to simply empty the RelatedBooks collection before deleting a book.
book.RelatedBooks.Clear();
session.Delete(book);
Cascading deletes is not typically done in a many-to-many relationship because it will delete the object at the other end of the relationship, in this case a Book.
This just got updated:
http://fluentnhibernate.lighthouseapp.com/projects/33236/tickets/115-self-referencing-relationships