Duplicate Records when they should be unique - c#

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!

Related

Entity ORM Joining Two Tables Off ID ForeignKey given non-foreignkey?

I have a string, name.
I have two tables:
Table 1:
|---------------------|------------------|
| ID | PadName |
|---------------------|------------------|
| 12 | "Hello" |
|---------------------|------------------|
Table 2
|------------------------------------------|------------------|
| MetaDataID (FK to ID in table1) | .......... |
|------------------------------------------|------------------|
| 12 | Other Data..
|------------------------------------------|------------------|
Example Query:
Select ID from table1 given a padName the join that ID with table2.
I'm using entity framework in C# and what I want is to feed in a PadName in Table 1 and then get all the associated Table 2 data where the ID fields match (since table2 has an FK relationship to table 1).
I've seen some example code like the following:
var query = _context.PadMetaData
.Where(x => x.PadName == padName).Select(p => new { p.id });
Then I want to take that id result and join it with the MetaDataId in table2.
But I can't seem to achieve what I want.

Why there is no LastOrDefault method in petapoco like FirstOrDefault?

Let's say this is my table TicketUpdate in SQL Server with some data inside:
_______________________________
| Id | TicketId | Description |
-------------------------------
| 1 | 5 | desc1 |
| 2 | 6 | desc2 |
| 3 | 5 | desc3 |
| 4 | 5 | desc4 |
| 5 | 6 | desc5 |
I want to retrieve the last row with TicketId = 5 in using Petapoco.
There are several methods for retrieving single row like FirstOrDefault which looks like:
db.FirstOrDefault<TicketUpdate>("select * from TicketUpdate where TicketId = 5");
But using this statement it returns the first row with value of TicketId = 5 with a description of desc1.
My question is how can I retrieve the LastOrDefault value then? There is no such methods in Petapoco.
Additional info
Temporarily I can retrieve the last row with TicketId = 5 by nesting the query like
select *
from TicketUpdate
where Id = (select MAX(Id) from TicketUpdate where TicketId = 5)
But is there any methods or better approach for finding the last row like we retrieve First row by using FirstOrDefault method, without nesting the query?
As mentioned in the comments, you should be able to sort your data first.
Try something like this:
db.FirstOrDefault<TicketUpdate>("select TOP 1 * from TicketUpdate where TicketId = 5 orderby [Id] desc");
As long as Id is incremented it should return the last item added for TicketId == 5.
Change your query to get the last record where ID is max. Also you need to use Top 1 to get only one record.
select Top 1 * from TicketUpdate where TicketId = 5 order by ID desc

Combining Characters with Id Field

I'll create an Issue table in an MVC5 application and I want to use special code for each type of the issues as below:
For IT related questions INF-0001, INF-0002, ...
For General type of questions GEN-0001, GEN-0002, ...
As I use all the issues on the same table, I think it is better to store the ID numbers as INF-0001, GEN-0001, ... etc. In that case should I use string as the data type of ID column in MSSQL? Or what is the best approach in order to store Id's with their related codes? I also think of using GUID, but I am not sure if it is possible. Thanks in advance.
I suppose it's better create separate field for your custom names. So your table will have int Id (Primary Key) field and CustomName varchar(100) or nvarchar(100) type (If you use unicode characters) field with your custom names.
It will be better for perfomance to use int as Id if you will JOIN your file table with others. If you want to search values in this field and it is slow just create INDEX.
You could have a general issue id and a category, for example:
Table: Issue
------------------------------------
IssueID | CategoryID | CategoryIndex
------------------------------------
1 | 1 | 1
2 | 1 | 2
3 | 2 | 1
4 | 1 | 3
Table: Category
-----------------------------
CategoryID | Prefix | Name
-----------------------------
1 | INF | IT
2 | GEN | General
Then you calculate the issue number when querying these tables.
You can store the calculated number in a table if you want to keep track of the issue number in case of a change in the database (ex: the prefix for IT related questions changes from INF to IT)
Now that you have a good schema, how do you keep control of the category sequence on the issues table? Check this out:
DECLARE #categoryID INT
DECLARE #nextSequence INT
SET #categoryID = 1 --You'll have to change this!
SELECT #nextSequence = i.CategoryIndex
FROM Issue i
WHERE i.CategoryID = #categoryID
SELECT COALESCE(#nextSequence, 0) + 1 as 'NextSequence'
You can turn that into a stored procedure (NextSequence, maybe?) that receives an INT as parameter (the category ID) and returns another INT as result (the CategoryIndex for the new issue).
Finally, to create your full code:
SELECT
i.IssueID
, c.Prefix + '-' + RIGHT('0000' + CONVERT(VARCHAR(4), i.CategoryIndex), 4) as 'IssueCode'
FROM Issue i
INNER JOIN Category c ON i.CategoryID = c.CategoryID

How to use Linq To Sql query to show the data in my case?

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();

How to get rid of multiple columns in a database?

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.

Categories

Resources