Database Hotel Reservation - c#

So i have a bit of a problem, on my ASP.Net website i want it to show all the rooms which are currently available and not in use. When i say not in use i mean at present there is no one reserved to that room, so the systemdate is not between any values of the checkin and checkoutdate.
Part of my schema:
CREATE TABLE "Rooms"(
RoomNo int NOT NULL,
RoomType nvarchar(20) NULL,
PricePerNight money NULL,
MaximumOccupancy int NULL,
NoOfBeds int NULL,
NoOfBathrooms int NULL,
Entertainment bit NULL,
RoomService bit NULL,
Gym bit NULL,
CONSTRAINT PK_Rooms PRIMARY KEY(RoomNo)
)
CREATE TABLE "Reservation"(
ReservationID int IDENTITY (1,1) NOT NULL,
CustomerID int NOT NULL,
RoomNo int NOT NULL,
CheckInDate date NOT NULL,
CheckOutDate date NOT NULL,
NoOfDays int NOT NULL,
CONSTRAINT PK_Reservation PRIMARY KEY(ReservationID),
CONSTRAINT FK_Reservation_Customers_CustID FOREIGN KEY(CustomerID)
REFERENCES dbo.Customers(CustomerID),
CONSTRAINT FK_Reservation_Rooms_RoomNo FOREIGN KEY(RoomNo)
REFERENCES dbo.Rooms(RoomNo)
)
So heres my idea, im assuming im going to need an sql query which goes something like this:
Select All FROM Rooms Where &CheckInDate != "Select CheckIndate From
Reservation" AND &CheckOutDate != "Select CheckOutDate From
Reservation".
But this has some flaws in it.
Can someone please tell me how i can do this, how i can make my Sue-do-code (lets call it) more viable, as i'm not sure if something like that will work, and if necessarily suggest improvements i could make to my schema.
TLDR; i need a query where someone enters a checkindate and checkoutdate and it returns all the rooms which are available.

Try this..
SELECT *
FROM Rooms
WHERE NOT EXISTS
(SELECT *
FROM Room r, Reservation rs
WHERE r.RoomNo = rs.RoomNo AND GETDATE() BETWEEN rs.CheckInDate AND rs.CheckOutDate)

This is what i wanted.
SELECT dbo.Rooms.RoomNo
FROM dbo.Rooms JOIN dbo.Reservation
ON (dbo.Rooms.RoomNo = dbo.Reservation.RoomNo)
WHERE '2012-01-01' NOT BETWEEN dbo.Reservation.CheckInDate AND dbo.Reservation.CheckOutDate
AND '2012-01-05' NOT BETWEEN dbo.Reservation.CheckInDate AND dbo.Reservation.CheckOutDate;
Took time but i got it in the end. the where statement initial date can be replaced with &Date.

Related

INSTEAD OF SQL Server trigger using C# code that can better than update

I have a table and I fill one of the columns with a trigger if it is null or empty. I want to delete the trigger and do its job in code.
Do I have to first insert and after update or is there a better way?
In .NET Framework, ORM is NHibernate
CREATE TABLE [dbo].[Table]
(
[Id] INT NOT NULL PRIMARY KEY,
[Col1] NVARCHAR(50) NOT NULL,
[Col2] NVARCHAR(50) NOT NULL,
[Code] NVARCHAR(100) NULL
);
CREATE TRIGGER Update_Table
ON [dbo].[Table]
AFTER INSERT
AS
BEGIN
DECLARE #id INT
SELECT #id = Id
FROM inserted
UPDATE [dbo].[Table]
SET Code = 'CODE' + Id
FROM [dbo].[Table]
WHERE Id = #id AND Code IS NULL
END
I did this
Table entity = new Table() { Col1 = "aaa", Col2 = "bbb" };
entity = _repo.insert(entity);
entity.Code = "CODE" + entity.Id;
_repo.Update(entity);
sometimes i do not need update. Because users send this column value.
Table entity = new Table() { Col1 = "aaa", Col2 = "bbb", Code = "ccc" };
entity = _repo.insert(entity);
I tried insert then update. It is OK. Just seeking a better way.
I would simplify it by making CODE computed column, like this
CREATE TABLE [dbo].[Table]
(
[Id] INT NOT NULL PRIMARY KEY,
[Col1] NVARCHAR(50) NOT NULL,
[Col2] NVARCHAR(50) NOT NULL,
[Code] AS 'Code' + CAST(Id as NVARCHAR)
)
so, when inserting data, Code will be populated automatically
Notwithstanding Nino's answer, an interceptor is common way to achieve this.
Update:
It appears that event listeners are also an applicable technique too: https://stackoverflow.com/a/867356/1162077
You don't say how you're generating the entity id when it's not supplied by, so the event you intercept/handle will depend on how you're doing that.

ASP.NET SQL elimininate duplicate Ids

I have two database tables for documenting a wound healing progression. Those are joined over the wound_id-Column like this:
So for one wound, I can create many progresses to show the healing of it. This is working fine.
Here is the code for the tables:
Table wound_details:
CREATE TABLE [dbo].[epadoc_mod_wound_details] (
[wound_id] INT IDENTITY (1, 1) NOT NULL,
[wound_type] VARCHAR (500) NULL,
[wound_description] VARCHAR (500) NULL,
[decuGrade] INT NULL,
[wound_comments] VARCHAR (500) NULL,
[wound_timeReal] DATETIME NULL,
[wound_timeGiven] DATETIME NULL,
[casenumber] INT NULL,
[username] VARCHAR (50) NULL,
[infectionstate] VARCHAR (50) NULL,
PRIMARY KEY CLUSTERED ([wound_id] ASC)
);
Table wound_progress:
CREATE TABLE [dbo].[epadoc_mod_wound_progress] (
[progress_id] INT IDENTITY (1, 1) NOT NULL,
[wound_length] INT NULL,
[wound_width] INT NULL,
[wound_depth] INT NULL,
[wound_surrounding] VARCHAR (500) NULL,
[wound_consistence] VARCHAR (500) NULL,
[wound_state] VARCHAR (200) NULL,
[wound_painscale] INT NULL,
[wound_itch] INT NULL,
[wound_id] INT NULL,
PRIMARY KEY CLUSTERED ([progress_id] ASC),
CONSTRAINT [FK_epadoc_mod_wound_progress_fk] FOREIGN KEY ([wound_id]) REFERENCES [dbo].[epadoc_mod_wound_details] ([wound_id]) ON DELETE CASCADE
);
Then I wrote a SELECT-Query to show all wounds for specific case number which are documented for the patient:
SELECT DISTINCT
dbo.epadoc_mod_wound_details.wound_id, dbo.epadoc_mod_wound_details.casenumber, dbo.epadoc_mod_wound_details.wound_type, dbo.epadoc_mod_wound_progress.progress_id, dbo.epadoc_mod_wound_details.wound_comments, dbo.epadoc_mod_wound_details.wound_timeReal, dbo.epadoc_mod_wound_details.username
FROM dbo.epadoc_mod_wound_details LEFT JOIN
dbo.epadoc_mod_wound_progress
ON dbo.epadoc_mod_wound_details.wound_id = dbo.epadoc_mod_wound_progress.wound_id
WHERE dbo.epadoc_mod_wound_details.casenumber = #casenr;
This is working fine though, but the problem is that ALL wound progresses are shown in the GridView, here is an example so you can see what I mean:
What I want to do is just show the latest progress of one wound, so for the above example just show the last entry with progressID 65:
33 65 1111111 Dekubitus
34 .. ....... .........
The SELECT DISTINCT approach didn't work and I also tried with MAX(progressID) but I always seem to get errors. I think I have to do something with ORDER BY or a second SELECT-Query before the JOIN.
Thanks for any advice!
You should use GROUP BY combined with MAX in your query.
SELECT
dbo.epadoc_mod_wound_details.wound_id,
dbo.epadoc_mod_wound_details.casenumber,
dbo.epadoc_mod_wound_details.wound_type,
MAX(dbo.epadoc_mod_wound_progress.progress_id) AS progress_id,
dbo.epadoc_mod_wound_details.wound_comments,
dbo.epadoc_mod_wound_details.wound_timeReal,
dbo.epadoc_mod_wound_details.username
FROM
dbo.epadoc_mod_wound_details
LEFT JOIN
dbo.epadoc_mod_wound_progress ON
dbo.epadoc_mod_wound_details.wound_id = dbo.epadoc_mod_wound_progress.wound_id
GROUP BY
dbo.epadoc_mod_wound_details.wound_id,
dbo.epadoc_mod_wound_details.casenumber,
dbo.epadoc_mod_wound_details.wound_type,
dbo.epadoc_mod_wound_details.wound_comments,
dbo.epadoc_mod_wound_details.wound_timeReal,
dbo.epadoc_mod_wound_details.username;
Since you only want the progress_id, The easies way to do it is using a correlated subquery:
SELECT wound_id,
casenumber,
wound_type,
(
SELECT TOP 1 progress_id
FROM dbo.epadoc_mod_wound_progress AS WP
WHERE WP.wound_id = WD.wound_id
ORDER BY progress_id
) As progress_id,
wound_comments,
wound_timeReal,
username
FROM dbo.epadoc_mod_wound_details As WD
WHERE casenumber = #casenr;
I understand you need each record of "epadoc_mod_wound_details" with the latest record of "epadoc_mod_wound_progress".
You can try this:
select wound.wound_id, wound.casenumber, wound.wound_type,
wound.wound_comments, wound.wound_timeReal, wound.username, MAX(progress_id)
from epadoc_mod_wound_details wound
left join epadoc_mod_wound_progress progress on wound.wound_id = progress.wound_id
where wound.casenumber = ''
group by wound.wound_id, wound.casenumber, wound.wound_type,
wound.wound_comments, wound.wound_timeReal, wound.username

ASP.NET MVC 5 - LINQ Query to Select Data from Database

I'm working on a school project in ASP.NET MVC 5. The project is about creating a social network. After the user logs in, he will see all public posts on his newsfeed.
I am having issues, though, in showing the public posts' data from the database.
This is the script of the database :
create table Utilizador(
id_utilizador integer not null identity(1,1),
nome varchar(50) not null,
apelido varchar(50) not null,
username varchar(15) not null unique,
pass varchar(50) not null,
email varchar(50) not null unique,
sexo char(1) not null CHECK (sexo IN('M', 'F')),
paĆ­s varchar(50) not null,
imagem_perfil varchar(50) not null,
data_nascimento date not null,
estado int not null default 2, --0->Bloqueado 1-Activo, 2-por activar
primary key (id_utilizador),
check (email LIKE '%#%.%')
)
create table Post(
id_post integer not null identity(1,1),
texto varchar(400) not null,
primary key(id_post)
)
create table Publish_Post(
id_post integer not null,
id_utilizador integer not null,
data timestamp not null,
primary key(id_post),
foreign key(id_post) references Post(id_post),
foreign key(id_utilizador) references Utilizador(id_utilizador)
)
create table Privacy(
id_privacidade integer not null identity(1,1), --> 1 public, 2 private
nome varchar(50) not null,
primary key(id_privacidade)
)
create table Have_Privacy(
id_post integer not null,
id_privacidade integer not null,
primary key(id_post),
foreign key(id_post) references Post(id_post),
foreign key(id_privacidade) references Privacidade(id_privacidade)
)
Let me explain why I create the database the way I do:
The user creates and publishes some posts that have will have a privacy value (1 or 2). After the user logs in, all public posts(1) should appear on his newsfeed.
So far I have this LINQ query in C#:
var id_posts = from p in db.Posts
select p.texto;
ViewBag.Posts = id_posts;
Can someone help me?
Thanks in advance :)
Just do this
var id_posts = from p in db.Posts
join hp in db.Have_Privacy on p.id_post equals hp.id_post
join prv in db.Privacy on hp.id_privacidade equals prv.id_privacidade
where prv.nome = 'Private'
select p.texto;
Tell how it goes
Why not just add a field in Post called isprivate with boolean type of BIT that determines if it's private or not and then use query for provided data with where clause:
var id_posts = from p in db.Posts
where isprivate == false
select p.texto;
If you want to have more than 2 types of privacy and just stick with DB schema you provided, you can go with a JOIN:
If id decides it is private:
var id_posts = from p in db.Posts
join hp in db.Have_Privacy on p.id_post equals hp.id_post
where hp.id_privacidade = 1
select p.texto;
If name decides it is private:
var id_posts = from p in db.Posts
join hp in db.Have_Privacy on p.id_post equals hp.id_post
join prv in db.Privacy on hp.id_privacidade equals prv.id_privacidade
where prv.nome = 'Private'
select p.texto;
Also please note that naming tables in one language and columns in other is considered as bad design. It's hard for others (in this example me) to read it, even if I know what it should mean.
Two last queries use your schema with no changes implemented.

How to use sql defined functions as fields?

I am creating tables in Sql Management Studio 2012 using SQL. How do I make fields or columns with names that are already defined in Sql Server e.g User_ID, User_Name. I want to use them as fields in my tables.
Table definition from Duplicate Post:
create table Ticket(
Ticket_Id varchar(10) not null,
TicketType_Id varchar(3) not null,
Ticket_PurchaseDate DateTime null,
LottoDraw_Id int null,
User_Id int null,
Ticket_IsWinner bit null
Primary Key(Ticket_Id,TicketType_Id)
)
Warp the column name like in brackets [ ] ... such as
create table Ticket(
Ticket_Id varchar(10) not null,
TicketType_Id varchar(3) not null,
Ticket_PurchaseDate DateTime null,
LottoDraw_Id int null,
[User_Id] int null,
Ticket_IsWinner bit null
Primary Key(Ticket_Id,TicketType_Id)
)

How to get list of a table columns in EF?

I need a ColumnName of a table in EF which I have it's ID.
My Tables are something like this :
Retailers
[RetailerId] [int] IDENTITY(1,1) NOT NULL,
[RetailerName] [varchar](50) NOT NULL,
[StateName1] [bit] NOT NULL,
[StateName2] [bit] NOT NULL,
[StateName3] [bit] NOT NULL,
States
[SId] [int] IDENTITY(1,1) NOT NULL,
[StateName] [varchar](50) Not Null
I receive an SId from a function and need to select all retailers which are located in that State.
Something like:
var listOfRetailers = (from m in db.Retailers where m.[a column that it's id is equal to SId] == true select m ).toList();
From your comments I think this is what you are looking for. But design wise what you have done is bad. I will explain shortly.
var listOfRetailers;
if(SId == 1)
{
listOfRetailers = db.Retailers.select(r=> r.StateName1.Equals(true)).ToList();
}
else if(SId == 2)
{
listOfRetailers = db.Retailers.select(r=> r.StateName2.Equals(true)).ToList();
}
else if(SId == 3)
{
listOfRetailers = db.Retailers.select(r=> r.StateName3.Equals(true)).ToList();
}
EDIT
Technically this is a bad design. Coz you are making the assumption that your States table will have 3 records
1 - ACT
2 - NSW
3 - NT
For every state you are have a corresponding column in Retailers table StateName1, StateName2, StateName3
Lets say you want to introduce a 4th state (say 4 - VIC). Now you will need to introduce a new column called StateName4 in your Retailers table. (by doing this there will be code level and DB level changes)
Also with the new columns you are introducing additional overheard of unused/ redundant data.
since this is a many-to-many situation (one state can have many retailers and one retailer can be in many states), the best approach would be to create
3 tables (Retailer, State, RetailerState), where by RetailerState table will play the role of mapping entries from State, Retailer tables
Retailer
---------
[RetailerId]
[RetailerName]
State
------
[SId]
[StateName]
RetailerState
--------------
[RetailerId]
[SId]

Categories