C# Entity Framework and Linq - Insert into database using entity model - c#

I am trying to create a program to export excel content/data to a database created in SQL Server 2014. I already have the data (variables) I want to insert into database. Now i am having some problems on the database diagram, in other words how should I build it, and how can I insert those values on it.
This is suppose to be a school schedule to get some querys to other program (independent of this one), so this program is just for the database management.
Now I only have one table for tests, but I know i need to do relations between them.
Original Table (Fields):
(PK) Id
StartTime
EndTime
Teacher
Class
Room
Subject
DayWeek
So now I want to create independent tables, which in my head would be:
Rooms (Id, Room)
Classes (Id, Class)
Teachers (Id, Teacher)
Subjects (Id, Subject)
So the original fields would be replaced by those tables in a one to many relationship if I am not wrong.
So the question is, I don't know how to insert with the relationship, because if there is already one Room/Teacher/Subject/Class with the same name as my variable, I will not insert into the respective table.
May some one help this newbie ^^?
Thanks and sorry for my bad english.
Edit:
Thanks for your answer, but I guess that isn't my problem.
So my database would be like this (any suggestion is welcome to improve the database structure):
Tables (and Fields):
Schedule (Id (PK), StartTime, EndTime, DayWeek, RoomId (FK), ClassId (FK), SubjectId (FK), TeacherId (FK))
Rooms (RoomId (PK), RoomName)
Classes (ClassId (PK), ClassName)
Subjects (SubjectId (PK), SubjectName)
Teachers (TeacherId (PK), TeacherName)
So the table Schedule have many relationships to different tables (One to Many, if i am not wrong).
Being more specific, the whole database is empty, with those tables and relationships created.
I am filling those tables with data from some excel files, I already read them and got them to variables, in concrete i got these values to variables, from a excel: StartTime, EndTime, DayWeek, Room, Class, Subject, Teacher.
My problem is I want to insert these values into the table Schedule since it will be the table that i want to get information, but for that I need to also insert data to the "foreign tables". So can you try to help me?
In my way of thinking since I don't have much SQL knowledge I would "ask"/select the Id of every Foreign table record (e.g.: I would get the id of the room/teacher/subject/class (variable got by excel) in the respective foreign table. If exist I would get the id and then i already have the id to insert into schedule table, else I would insert into Foreign table that field and get the id to the schedule table), is this way of thinking right, or there is a easiest way?
This database will only be written once per yer, since I will insert all the teachers schedules into it.

The original fields would be replaced by the Id of order table (foreign key).
If you wanna insert into origin table, your must have data in foreign table, you must have room,teacher, class, ...ect.
And the code will look like this, take example:
context.Fields.Add(new Field { StartTime = ...,......TeacherId = 5,ClassId =6,...ect});
Original Table (Fields):
(PK) Id
StartTime
EndTime
TeacherId
ClassId
RoomId
SubjectId
DayWeek

Related

How to save date student's absence in SQL Server?

I have student table in SQL Server.
In my web application I have textBox, where I can input a date (dd-mm-yyyy). This date means that any(application know which exactly) student was absent this day.
How to save this date in SQL Server?
There is no problem when student is absent just one day per all life, because I can create one additional column in my student table and save there date of absent.
But I don't know how many days student will absent. I can add thousand columns to my student table and write in there dates of absents, but it's very bad solution.
So, how to save dates of absence in SQL?
I wrote my web application in ASP.NET, C#, SQL Server.
You need to have another table to keep track of the dates the student was absent.
Say your current table is as follows:
Student
-------
StudentId [PK]
...
So you would now create another table as:
StudentAbsent
-------
StudentAbsentId [PK]
StudentId [FK, Student.StudentId]
AbsentDate
To get the dates the student with id=5 was absent you'd do something like the following in SQL
SELECT AbsentDate FROM StudentAbsent
WHERE StudentId = 5
Oh and BTW you'd want to read more on relationships. If it's a 1-1 relationship one row of table1 is related to one row of table2.
If it's a 1-n relationship, one row of table1 is related to many rows of table2 (as is the case above)
If it's a n-n relationship, one row of table1 is related to many rows of table2 and vice-versa.
You have to create another table called absents with three columns:
id (primary index and auto_increment)
student_id (should not be unique)
date
The id column is just the id of the absent (it's a good practice to have id for every row on a table). The student_id is a reference to id column of students table, identifying the correct student. And the date column is the date of absent.
Another good practice is to create relationship internally and set triggers to actions like delete (what should you do if the student is deleted?).

Implement C# migration code in SQL

I am new to SQL and today I got assigned an important task - to create a migration script for data in a table. From my understanding, a migration script is copying data from table A and move it to other tables B and C and so on. This seems to be frequent when database designs change constantly and the team wants to preserve data.
My task:
I have a JobOffer table, with the CityId field. Now the team wants to delete that field, and to preserve information they will add the CityId to the Address table and connect both tables using an intermidiary table called Location (this allows a JobOffer to have several Addresses).
I have no idea on how to perform this task. An analogy in c# of what I prentend is this:
foreach (var row in JobOffer)
{
int addressId;
if (!Address.Contains(row.CityId)){
addressId = Address.add(row.CityId);
Locaion.add(row.JobOfferId, addressId);
}
else
{
Locaion.add(row.JobOfferId, Address.get(row.CityId));
}
}
How do I do it in SQL?
You need three tables - one for the candidates, one for the addresses (locations) and one that links the two. The third table is necessary because what you described is a many to many relationship. A single candidate may have multiple locations and a single location may house multiple candidates.
When I created similar to yours it took two scans of the input data:
The first checked if I had all the locations. If any were missing I inserted it into the location table.
The second scan inserted data into the candidate and canditatelocs table. At this point I knew for sure that I had an address for every candidate in the locations table.
Here is a description of the tables:
create table candidate (candidateid int identity primary key, idate datetime default getdate(), name varchar(200))
create table candidatelocs (candidateid int, locid int)
create table locations ( locid int identity primary key, city varchar(500), state varchar(500))

insert a row in a table that links with PK autoincrement of another table

I have two tables
contact table
contactID (PK auto increment)
FirstName
LastName
Address
etc..
Patient table
PatientID
contactID (FK)
How can I add the contact info for Patient first, then link that contactID to Patient table
when the contactID is autoincrement (therefore not known until after the row is created)
I also have other tables
-Doctor, nurse etc
that also links to contact table..
Teacher table
TeacherID
contactID (FK)
So therefore all the contact details are located in one table.
Is this a good database design?
or is it better to put contact info for each entity in it's own table..
So like this..
Patient table
PatientID (PK auto increment)
FirstName
LastName
Address
Doctor table
DoctorID (PK auto increment)
FirstName
LastName
Address
In terms of programming, it is easier to just have one insert statement.
eg.
INSERT INTO Patient VALUES(Id, #Firstname,#lastname, #Address)
But I do like the contact table separated (since it normalize the data) but then it has issue with not knowing what the contactID is until after it is inserted, and also probably needing to do two insert statements (which I am not sure how to do)
=======
Reply to EDIT 4
With the login table, would you still have a userid(int PK) column?
E.g
Login table
UserId (int PK), Username, Password..
Username should be unique
You must first create the Contact and then once you know its primary key then create the Patient and reference the contact with the PK you now know. Or if the FK in the Patient table is nullable you can create the Patient first with NULL as the ContactId, create the contact and then update the Patient but I wouldn't do it like this.
The idea of foreign key constraints is that the row being referenced MUST exist therefore the row being referenced must exist BEFORE the row referencing it.
If you really need to be able to have the same Contact for multiple Patients then I think it's good db design. If the relationship is actually one-to-one, then you don't need to separate them into two tables. Given your examples, it might be that what you need is a Person table where you can put all the common properties of Doctors, Teachers and Patients.
EDIT:
I think it's inheritance what you are really after. There are few styles of implementing inheritance in relational db but here's one example.
Person database design
PersonId in Nurse and Doctor are foreign keys referencing Person table but they are also the primary keys of those tables.
To insert a Nurse-row, you could do like this (SQL Server):
INSERT INTO Person(FirstName) VALUES('Test nurse')
GO
INSERT INTO Nurse(PersonId, IsRegistered) VALUES(SCOPE_IDENTITY(), 1)
GO
EDIT2:
Google reveals that SCOPE_IDENTITY() equivalent in mysql is LAST_INSERT_ID() [mysql doc]
EDIT3:
I wouldn't separate doctors and nurses into their own tables so that columns are duplicated. Doing a select without inner joins would probably be more efficient but performance shouldn't be the only criteria especially if the performance difference isn't that notable. There will many occasions when you just need the common person data so you don't always have to do the joins anyway. Having each person in the same table gives the possibility to look for a person in a single table. Having common properties in a single table also allows you have to have doctor who is also a patient without duplicating any data. Later, if you want to have more common attributes, you'd need to add them to each "derived" table too and I will assure you that one day you or someone else forgets to add the properties in one of the tables.
If for some reason you are still worried about performance and are willing to sacrifice normalization to gain performance, another possibility is to have all person columns in the same table and maybe have a type column there to distinguish them and just have a lot of null columns, so that all the nurse columns are null for doctors and so on. You can read about inheritance implementation strategies to get an idea of even though you aren't using Entity Framework.
EDIT4:
Even if you don't have any nurse-specific columns at the moment, I would still create a table for them if it's even slightly possible that there will be in the future. Doing an inner join is a pretty good way to find the nurses or you could do it in the WHERE-clause (there a probably a billion ways to do this). You could have type column in the Person table but that would prevent the same person being a doctor and a patient at the same time. Also in my opinion separate tables is more "strict" and more clear for (future) developers.
I would probably make PersonId nullable in the User table since you might have users that are not actual people in the organization. For example administrators or similar service users. Think about in terms of real world entities (forget about foreign keys and nullables), is every user absolutely part of the organization? But all this is up to you and the requirements of the software. Database design should begin with an entity relationship design where you figure out the real world relationships without considering how they will be mapped to a relational database. This helps you to figure out what the actual requirements are.

Filtering entities with EF behind two joins without bringing the whole tables into datamodel

Consider the following case, I have three tables
LampPost, columns: Id (PK, int), StreetId (FK, int)
Street, columns: Id (PK, int), CityId (FK, int)
City, columns: Id (PK, int), Name (varchar)
The usual case is that there are a lot (tens of thousands) of LampPosts per City. Let's say I'm creating a LampPost managing system, and I want to be able to filter LampPosts by city. But all I know about the table City is that it contains the two columns listed above. On one server, it might have additional columns, which I do not care about. And the same goes for the table Street.
Currently I have all the tables in my datamodel, which allows queries such as context.LampPosts.Where(lp => lp.Street.City.Name == "Paris"), but I'd really want to have another way of accomplishing this, without brining in the whole tables.
I also tried adding the tables to my data model (I'm using database first, EF 5 on .NET 4.0) and just removing the unneccessary columns, but EF complained about unmapped columns.
I'm pretty sure this can be done by either stored procs or some sort of executequery -calls, but I am very unfamiliar with both so I'm asking you guys, what would be the best way to go about this?
One way could be creating a view for the table and select only required columns. Then you can bring the view into the data model.
For example if your City talbe looks like:
City (Id, Name, State, Population, Area)
you create a view for it like this:
CREATE VIEW CityView AS
SELECT Id, Name FROM City
and if Street looks like this:
Street (Id, Name, CityId, Length, Width)
(the columns are just for demonestration)
you can create it's view like:
CREATE VIEW StreetView AS
SELECT Id, Name, CityId FROM Street
All the required columns to navigate between entities are available.

Logic for creating an attendance system in c# and any database(help needed with the db schema)

I have to create an attendance management system of our college..
.the Requirements are..
there are 6 subjects
every subject has a table for every month..
every class conducted is recorded and is numbered from 1 to n..and the present candidates are given the count if present...
at the end of every month, total classes taken by all 6 subjects are summed up...and total classes attended by each student is summed up and a percentage is calculated...(total present classes)/(total classes )*100...
there are 120 students...
please help me create an efficient way to create the databases...
note....
the application should allow you to view through all the absent classes he did not attend for reference..(so every absent class must be recorded)
My..attempts:
one way i tried was:
create tables for each subject...then
6 tables required
cons:
*every day must be a column and the copy of 6 tables should be created every month.
i.e 6 sub*12 months =72 tables every year
also a extra classes can be taken per subject...so if a subject is taken twice on the day,3 cases arrive--> present for both,absent for both,present for only one..*
2..the second method I've tried is:
create a table for each student with the same db schema ..(with subjects as columns )
con:
12 students will require 120 tables
:P
Any bright ideas guys...would really help if you give me ideas how to construct a db schema for this kinda application.......
thankyou.....
Students table:
StudentID int identity PK
LastName string(20)
FirstName string(20)
Classes Table:
ClassID int identity PK
ClassName string(50)
SubjectID int FK to Subjects table (not shown)
TermID int FK to Terms table (not shown)
Students to Classes table:
STCID int identity PK
ClassID int FK to Classes table
StudentID int FK to Students table
Attendance Table:
AttendID int identity PK
STCID int FK to Student To Class table
Date date/time
PK means Primary Key. FK means Foreign Key (it associates to the Primary Key in other tables).
The Students to Subjects table connects the students with their subjects. For each subject that a student is assigned, add a record to the Students to Subjects table. For each date that a student attends a particular subject, add a single record to the Attendance table.
First of all, you definitely do not need to duplicate tables for each month or student. That's madenss.
You can calculate the month from the date, so just storing a date solves that.
Here's my initial reaction.
You need tables for students, subjects, registrations, classes and attendence.
Registrations table:
ID
Student_ID
Subject_ID
Classes table (use a different name) shows all of the valid class dates (required to calculate attendance %):
ID
Subject_ID
Class_Date
Attendance table:
ID
Student_ID
Class_ID (refers to the ID field in the class table)
(modify the names to suit your conventions)
This way attendance contains a record of every appearance by every student in every class. You can determine which classes each student missed in each subject by SQL queries.
All of the logic you described can be handled with this structure unless I missed something. Keep your data model clean and let your code do the work.
Here's some SQL DDL based on #nycdan's answer but using natural keys rather than artificial (surrogate?) keys because doing so allows for improved referential integrity i.e. Attendance can and should reference Enrollment to ensure attendance cannot be logged for a student who is not registered on that course. I've also changed a few names. I'm only including the most salient attributes. :
CREATE TABLE Students (student_ID INTEGER NOT NULL UNIQUE);
CREATE TABLE Courses (course_ID CHAR(6) NOT NULL UNIQUE);
CREATE TABLE Enrollment
(
course_ID CHAR(6) NOT NULL
REFERENCES Courses (course_ID),
student_ID INTEGER NOT NULL
REFERENCES Students (student_ID),
UNIQUE (course_ID, student_ID)
);
CREATE TABLE CourseSchedules
(
course_ID CHAR(6) NOT NULL
REFERENCES Courses (course_ID),
class_date DATE NOT NULL,
UNIQUE (course_ID, class_date)
);
CREATE TABLE Attendance
(
student_ID INTEGER NOT NULL,
course_ID CHAR(6) NOT NULL,
class_date DATE NOT NULL,
FOREIGN KEY (course_ID, student_ID)
REFERENCES Enrollment (course_ID, student_ID),
FOREIGN KEY (course_ID, class_date)
REFERENCES CourseSchedules (course_ID, class_date),
UNIQUE (course_ID, class_date, student_ID)
);

Categories

Resources