ASP NET CORE - Using EF Core
Table:
UserBooksId - Primary Key
UserId - the userId from another table
BookId - the bookId from another table
BookToBuy - where i keep my content
NrBooksOrdered - the number of the books ordered
So I don't know how to acces the content of this table using the UserId - > BookToBuy and NrBooksOrdered or even all the Primary Keys that have this userId.
Primary Key being unique, doesn't help me to much, because in the database, the UserId can be in the database multiple times, as well the bookid.
Example:
UserBookId:0 | UserId:1 | BookId:2 | BookToBuy:Wizzard | NrBooksOrdered:2
UserBookId:1 | UserId:1 | BookId:2 | BookToBuy:Wizzard | NrBooksOrdered:6
UserBookId:2 | UserId:1 | BookId:3 | BookToBuy:LongRoad | NrBooksOrdered:1
As you can see the UserId doesn't change.
Thank you.
You can use basic linq queries here
/* b is a reference here to every book, so you can filter it by the bool-expression */
var booksQuery = dbcontext.BooksTable.Where(b => b.UserId == 1 && b.BookId == 2);
/* books will be type of IQueryable so it isnt retrieved from the database */
/* yet. To do so, you can use `.ToList()` or `.AsEnumerable()` (wich is */
/* faster in use-cases, where you need to iterate the result once) */
var booksFromDb = booksQuery.AsEnumerable();
For a detailed description, on how to query data with EF-Core you can always refer back to: MS-Docs Querying Data
I need your help with an SQL query, that I am trying to build in C# Dataset Query Builder...
SELECT HouseHold.HHID, Client.FIRST_NAME, Client.LAST_NAME
FROM ((Client
INNER JOIN HouseHold_Client ON Client.CID = HouseHold_Client.CID)
INNER JOIN HouseHold ON HouseHold_Client.HHID = HouseHold.HHID)
Above code gives me the list of all HouseHolds (their ID) with Clients belonging to them:
HHID | FIRST_NAME | LAST_NAME
------------------------------
1 | Penelope | Grant
1 | Brian | Dyer
2 | James | Newman
2 | Richard | Parsons
.. but I can't figure out how to get people belonging to same HouseHold to show up on the same line, like this for a Data Grid View later on:
HHID | I_FIRST_NAME | I_LAST_NAME | II_FIRST_NAME | II_LAST_NAME
-----------------------------------------------------------------
1 | Penelope | Grant | Brian | Dyer
2 | James | Newman | Richard | Parsons
I have found loads of very similar questions, but very few had the same exact problem to solve. The ones (one or two) that really had the same problem and it had a solution, I just couldn't twist around my problem.
Any help is very much appreciated...
Thank you very much,
AD
Since you have only 2 persons per household, you can use the trick to get the minimum and maximum client Id per household. This is done in a subquery.
SELECT
X.HHID,
C1.FIRST_NAME AS I_FIRST_NAME, C1.LAST_NAME AS I_LAST_NAME,
C2.FIRST_NAME AS II_FIRST_NAME, C2.LAST_NAME AS II_LAST_NAME
FROM
(( SELECT
HHID, Min(CID) AS MinCId, IIf(Max(CID)=Min(CID), Null, Max(CID)) AS MaxCId
FROM HouseHold_Client
GROUP BY HHID
) X
INNER JOIN Client AS C1
ON X.MinCId = C1.CID)
LEFT JOIN Client AS C2
ON X.MaxCId = C2.CID;
The purpose of the IIf() expression is to output the maximum client Id only if it is different from the minimum client Id. To also return a record when MaxCId is Null, a LEFT JOIN is required on C2.
I did not join the HouseHold table here, since we only need the HHID from it, which is also available in HouseHold_Client. You can of course join it as well, if you need other columns from it.
Subquery:
( SELECT
HHID, Min(CID) AS MinCId, IIf(Max(CID)=Min(CID), Null, Max(CID)) AS MaxCId
FROM HouseHold_Client
GROUP BY HHID
) X
Subqueries must be enclosed in parentheses and be given a name (here X). X acts as a normal table having the columns HHID, MinCId and MaxCId in the main query. It is grouped by HHID. I.e., it returns one row per HHID. Min(CID) returns the smallest CID and Max(CID) largest CID per HHID.
In the case where you have 2 clients per HHID, this means that Min and Max will yield these 2 clients. If you have only 1 client, then both Min and Max will return the same client. If this is the case, then the IIf will return Null instead of Max(CID) to avoid returning twice the same client.
I have a table that I'm trying to query using Linq to SQL
The table is very simple it has 5 columns:
- PersonID
- ADID
- Name
- PlaceID
- PlaceName
I have 2 records in my table and they have the same PersonID in both records but different PlaceID and PlaceName values:
001 | 001 | Person X | P01 | Place 1
001 | 001 | Person X | P02 | Place 2
When I query this in SQL I get exactly the 2 rows:
select * from myTable where PersonID = '001'
However, when I try to do it in LINQ:
List<myTable> PersonInfo = (from myInfo in db.myTable
where myInfo.PersonID == "001"
select myInfo).ToList();
I get a count of 2 in PersonInfo but they are the same record. What am I doing incorrectly?
What I found out was that 1st Entity Framework needs a primary key to operate correctly. After researching the table I was using I found out that there was a primary key but it was a combo key So once I put "Entity Keys" on both columns my select statement returned the correct data.
Thanks to #GertArnold and everyone else that helped me on this problem!
i have a trouble to write a query with Linq i explain better my case, i have a database with 2 tables as follow :
it is the first table ;
Hotel
HotelID (Nvarchar(10) - PK)
HotelName (Nvarchar (200))
and this one is the second table ;
Period
PeriodID (Int (inc) - PK)
_From (Datetime )
_To (Datetime)
HotelID(Nvarchar(10) - FK)
then in the second Table (Period) there is the FK (HotelID) to connect the 2 tables;
Happen sometime i have a HotelName that gets more periods(PeriodID) so my purpose is to show the data in an only one Row into a DataGrid, i show you an example as i want show the data in my DataGrid if there are more periods in the same HotelName:
| HotelName | From | To | From(2) | To(2) | From(3) | To(3) | From(4)| To(4) |
| Excelsior |12/5/10 |3/6/10 | 2/8/10 | 9/9/10 | 23/9/10 | 1/10/10| 2/11/11| 1/12/10|
so i ask do you have any idea/suggest about how to show the data in a DataGrid inside one Row using Linq To Sql ?
thanks so much for your attention .
Have a good time .
Cheers
This article explains working with hierarchical data binding: http://msdn.microsoft.com/en-us/library/aa478959.aspx
Then, create an object model which roughly maps to your database tables:
Hotel
- ID
- Name
- Bookings
- Booking 1 { From, To }
- Booking 2 { From, To }
- Booking n { From, To }
Your Linq should look something like this:
var hotels = _db.Hotel.Select();
foreach(var hotel in hotels)
hotel.Bookings = _db.Period.Where(x => x.HotelId == hotel.HotelId).Select();
I'm creating an Access DB for use in an C# application at school. I've not had much experience working with DB's so if this sounds stupid just ignore it. I want the user to be able to select all the classes that a certain student has had in our IT department. We have about 30 in all and the maximum that a person can take in 4 years of high school is 15. Right now my DB has 15 different columns for each class that a user could have. How can I compress this down to one column (if there is a way)?
Excellent question Lucas, and this delves into the act of database normalization.
The fact that you recognized why having multiple columns to represent classes is bad already shows that you have great potential.
What if we wanted to add a new class? Now we have to add a whole new column. There is little flexibility for this.
So what can be done?
We create THREE tables.
One table is for students:
Student
|-------------------------|
| StudentID | Student_Name|
|-------------------------|
| 1 | John |
| 2 | Sally |
| 3 | Stan |
---------------------------
One table is for Classes:
Class
------------------------
| ClassID | Class_Name|
------------------------
| 1 | Math |
| 2 | Physics |
------------------------
And finally, one table holds the relationship between Students and Classes:
Student_Class
-----------------------
| StudentID | ClassID |
-----------------------
If we wanted to enroll John into Physics, we would insert a row into the Student_Class table.
INSERT INTO Student_Class (StudentID, ClassID) VALUES (1, 2);
Now, we have a record saying that Student #1 (John) is attending Class #2 (Physics). Lets make Sally attend Math, and Stan attend Physics and Math.
INSERT INTO Student_Class (StudentID, ClassID) VALUES (2, 1);
INSERT INTO Student_Class (StudentID, ClassID) VALUES (3, 1);
INSERT INTO Student_Class (StudentID, ClassID) VALUES (3, 2);
To pull that data back in a readable fashion, we join the three tables together:
SELECT Student.Student_Name,
Class.Class_Name
FROM Student,
Class,
Student_Class
WHERE Student.StudentID = Student_Class.StudentID
AND Class.ClassID = Student_Class.ClassID;
This would give us a result set like this:
------------------------------
| Student_Name | Class_Name |
------------------------------
| John | Physics |
| Sally | Math |
| Stan | Physics |
| Stan | Math |
------------------------------
And that is how database normalization works in a nutshell.
So you have 15 columns (e.g. class1, class2, class3 ... class15)?
Looks like you have a classic many-to-many relationship. You should create a new table to relate students and classes.
student { StudentID, StudentName ... }
classes { ClassID, ClassName ... }
student_classes { StudentID, ClassID }
If you are tracking classes on a year-by-year basis, you could add a year column to the relationship as well:
student_classes { StudentID, Year, ClassID }
It sounds like you need to think about normalizing your database schema.
There is a many-to-many relationship between students and classes such that many students can take many classes and many classes can be taken by many students. The most common approach to handling this scenario is to use a junction table.
Something like this
Student Table
-------------
id
first_name
last_name
dob
Class Table
-----------
id
class_name
academic_year
Student_Class Table
-------------------
student_id
class_id
year_taken
Then your queries would join on the tables, for example,
SELECT
s.last_name + ', ' + s.first_name AS student_name,
c.class_name,
sc.year_taken
FROM
student s
INNER JOIN
student_class sc
ON
s.id = sc.student_id
INNER JOIN
class c
ON
sc.class_id = class.id
ORDER BY
s.last_name, sc.year_taken
One word of advice that I would mention is that Access requires you to use parentheses when joining more than table in a query, I believe this is because it requires you to specify an order in which to join them. Personally, I find this awkward, particularly when I am used to writing a lot of SQL without designers. Within Access, I would recommend using the designer to join tables, then modify the generated SQL for your purposes.
This is a normalisiation issue. In effect you are asking the wrong question. In stead ask yourself the question how can you store 0 or more classes_taken? What other details do you need to store about each class taken? E.g. just the class taken, or data taken, result, etc?
For example consider somethin like the following
table Student
id int
name varchar(25)
...
table classes
id int
name varchar(25)
...
table clases_taken
student_id int (foreign key to student.id)
class_id int (foreign key to class.id)
data_started datatime
result varchar(5)
tutor_id int (foreign key to tutor.id)
...
You should never have columns like class1, class2, class3, class4 etc in a database table. What you should have is a related table. Your stucture would be something like:
Student Table with the following columns
StudentID
StudentLastName
StudentFirstName
(and so forth for all the data to describe a student)
Then
Course table with the following columns
CourseId
CourseName
Then
StudentCourse Table with the following columns
StudentId
CourseID
CourseDate
Now to find out what courses the person took you join these tables together.
Something like:
Select StudentID,StudentLastName,StudentFirstName, CourseName, CourseDate
from Student
join StudentCourse on student. studentid = StudentCourse.StudentID
join Course on Course.courseID = StudentCourse.CourseID
Please read this link to start learning database fundamentals:
http://www.deeptraining.com/litwin/dbdesign/FundamentalsOfRelationalDatabaseDesign.aspx
How about no class columns in the student table. Setup a new table with student id and class id columns. Each row represents a class the student took. Maybe add more columns such as: the year/semester, grade, etc.