EF 6 Bridge Table Insert Not Working - sql

I am still trying to learn how to use EF and running into a problem with my bridge table.
When I try to create a new Order with associated Resources, I get the following SQL error:
{"Violation of PRIMARY KEY constraint 'PK_Resource_Type'. Cannot insert duplicate key in object 'dbo.Resource_Type'. The duplicate key value is (2).\r\nThe statement has been terminated."}
Code Looks like this
ResourceType resource = new ResourceType();
resource.ID = 2;
resource.Name = "Van"
order.resourceType().Add(resource)
db.Orders.Add(order);
db.SaveChanges();
Tables look like this
--Order table
CREATE TABLE [dbo].[Orders](
[Order_ID] [int] IDENTITY(1,1) NOT NULL,
[OrdernName] [varchar](100) NOT NULL,
CONSTRAINT [PK_Orders] PRIMARY KEY CLUSTERED
(
[Order_ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
--Resource Type table
CREATE TABLE [dbo].[Resource_Type](
[ResourceType_ID] [int] NOT NULL,
[ResourceType] [varchar] (30) NOT NULL
CONSTRAINT [PK_Resource_Type] PRIMARY KEY CLUSTERED
(
[ResourceType_ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
--Resource Type To Order table
CREATE TABLE [dbo].[Resource_Type_Order](
[ResourceType_ID] [int] NOT NULL,
[Order_ID] [int] NOT NULL
CONSTRAINT [PK_Resource_Type_Order] PRIMARY KEY CLUSTERED
(
[ResourceType_ID] ASC,
[Order_ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[Resource_Type_Order] WITH CHECK ADD CONSTRAINT FK_Order_Resource_Type_Order FOREIGN KEY([Order_ID])
REFERENCES [dbo].[Orders]([Order_ID])
GO
ALTER TABLE [dbo].[Resource_Type_Order] WITH CHECK ADD CONSTRAINT FK_Resource_Type_Order_Resource_Type FOREIGN KEY([ReosurceType_ID])
REFERENCES [dbo].[Resource_Type]([Resource_ID])
GO
Am I using the bridge table correctly? I want my bridge table to look like this, after I add an order (ID=1) with two resources (car ID=1 and van ID=2).

Related

Violation of primary key after switch partition (stage>dbo)

Would someone help, please, to get rid of the error:
Violation of PRIMARY KEY constraint 'PK_stmp_tst1'. Cannot insert duplicate key in object 'dbo.stmp_tst'. The duplicate key value is (1).
which occurs after switch partition of the table.
Full SQL Script below:
I. Create 2 equal tables in different schemas:
CREATE TABLE dbo.stmp_tst(
[inn] [varchar](20) NULL,
[id] [bigint] IDENTITY(1,1) NOT NULL,
CONSTRAINT [PK_stmp_tst] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
go
CREATE TABLE stage.stmp_tst(
[inn] [varchar](20) NULL,
[id] [bigint] IDENTITY(1,1) NOT NULL,
CONSTRAINT [PK_stmp_tst] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
II. Insert data into stage table.
insert into stage.stmp_tst (inn)
select '1111'
III. Switch-partition stage to dbo.
alter table stage.stmp_tst switch partition 1 to dbo.stmp_tst partition 1;
IV. Add data to dbo table.
insert into dbo.stmp_tst (inn)
select '1111'
V. We have the error:
Violation of PRIMARY KEY constraint 'PK_stmp_tst1'. Cannot insert
duplicate key in object 'dbo.stmp_tst'. The duplicate key value is
(1).
IV. Drop temporary tables:
drop table dbo.stmp_tst
drop table stage.stmp_tst
It can be solved by the query:
DBCC CHECKIDENT ('dbo.stmp_tst', RESEED);
but reseeding takes time.
Is it possible to do a switch-partition correctly without reseed?
Thank you.

How to turn off Sorting in group by function as it's taking much resource & not required in my case

I have a SQL query for which I am doing "group by", but sorting is not necessary.
I am joining 2 table,
roleMstr
aclMstr
roleAclMap
'roleMstr', 'aclMstr' are many to many & stored in 'roleAclMap'
I am trying to fetch acl assigned to that role & are active (due to soft delete) & group them to find assigned & total
When I checked in SQL Server Profiler, Sorting is taking 68%, & index scan 32%
BEGIN
DECLARE #RoleCode VARCHAR(20);
SET #RoleCode = 'CLN';
SELECT am.aclGroup, am.subAclGroup, SUM(CASE ram.roleCode WHEN #RoleCode THEN 1 ELSE 0 END) AS assignedChild, COUNT(*) AS totalChild
FROM aclMstr am
LEFT JOIN roleAclMap ram
ON am.acl_code = ram.acl_code AND ram.roleCode = #RoleCode
WHERE am.isActive = 1
group by am.aclGroup, am.subAclGroup;
END
Query plan executor text link1, link2
I am counting how many acl are assigned to the 'acl group' based on 'role code'
I am getting the sorted column too.
roleMstr contains roleCode
CONSTRAINT [pk_rolemstr_rolecode] PRIMARY KEY CLUSTERED
(
[roleCode] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
aclMstr contains aclCode, isActive, aclGroup, subAclGroup
CONSTRAINT [pk_aclmstr_aclcode] PRIMARY KEY CLUSTERED
(
[aclCode] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[roleAclMap](
[id] [int] IDENTITY(1,1) NOT NULL,
[roleCode] [varchar](20) NOT NULL,
[aclCode] [varchar](50) NOT NULL,
CONSTRAINT [pk_roleaclmap_id] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
CONSTRAINT [uk_roleaclmap_rolecode_aclcode] UNIQUE NONCLUSTERED
(
[roleCode] ASC,
[aclCode] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[roleAclMap] WITH CHECK ADD CONSTRAINT [fk_roleaclmap_aclmstr_aclcode] FOREIGN KEY([aclCode])
REFERENCES [dbo].[aclMstr] ([aclCode])
GO
ALTER TABLE [dbo].[roleAclMap] CHECK CONSTRAINT [fk_roleaclmap_aclmstr_aclcode]
GO
ALTER TABLE [dbo].[roleAclMap] WITH CHECK ADD CONSTRAINT [fk_roleaclmap_rolemstr_rolecode] FOREIGN KEY([roleCode])
REFERENCES [dbo].[roleMstr] ([roleCode])
GO
ALTER TABLE [dbo].[roleAclMap] CHECK CONSTRAINT [fk_roleaclmap_rolemstr_rolecode]
GO
If sort can be turned off through query somehow. The query will be executed within half of time.

SQL one to many relation table design, the right way

Plot: I need to book an Order which relies on 3 different type of Factory.
I have individual tables for both order and Factory. Now I need to make a one to many relations between Order and Booking Factory.
Order Table:
CREATE TABLE [dbo].[tbl_OrderInformation](
[OrderInformationId] [int] IDENTITY(1,1) NOT NULL,
[OrderId] [int] NOT NULL,
[OrderNo] [nvarchar](50) NOT NULL,
CONSTRAINT [PK_tbl_OrderInformation] PRIMARY KEY CLUSTERED
( [OrderInformationId] ASC)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE =
OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
Factory Table:
CREATE TABLE [dbo].[tbl_Factory](
[FactoryId] [int] IDENTITY(1,1) NOT NULL,
[FactoryName] [nvarchar](50) NOT NULL,
[FactoryType] [nvarchar](50) NOT NULL,
CONSTRAINT [PK_tbl_Factory] PRIMARY KEY CLUSTERED
( [FactoryId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
Sample Order Data
Sample Factory Data
Now, an Order relies on multiple garments, dyeing, and printing Factory.
Suppose, Order C101 relies on Garments-A, Dyeing-A, Printing-A, Printing-B, Printing-C.
Now, I can design OrderBooking table in 2 ways.
CREATE TABLE [dbo].[tbl_OrderBooking_1](
[OrderBookingId] [INT] IDENTITY(1,1) NOT NULL,
[OrderId] [INT] NOT NULL,
[FactoryId] [INT] NULL,
[FactoryType] [NVARCHAR](50) NULL,
CONSTRAINT [PK_tbl_OrderBooking_1] PRIMARY KEY CLUSTERED
(
[OrderBookingId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
This the data will look like below:
And The second way,
CREATE TABLE [dbo].[tbl_OrderBooking_2](
[OrderBookingId] [INT] IDENTITY(1,1) NOT NULL,
[OrderId] [INT] NULL,
[garmentsFactoryId] [INT] NULL,
[dyeingFactoryId] [INT] NULL,
[printingFactoryId] [INT] NULL,
CONSTRAINT [PK_tbl_OrderBooking_2] PRIMARY KEY CLUSTERED
(
[OrderBookingId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
Here the data will look like,
Now, which approach of designing the OrderBooking table is more accurate and why ?
Please keep in mind that the type of factory is fixed to 3, and OrderBooking table will grow quite large over time thus tend to have heavy read and write operations.
The link table between Order & factory would be the best approach.
You will get better performance and you can create indexes on the numeric columns.
Going forward if you have any new factory then it is also each to insert without any issue.
The link table will help you to align with the Normalization rule as well. so my suggestion is go with that.

UNIQUE Constraint For Columns On Different Tables

I have three tables a,b,and c each with an int IDENTITY PK field that relates to the child table.
CREATE TABLE [dbo].[a]([aID] [int] IDENTITY(1,1) NOT NULL,[aCode] [varchar](20) NOT NULL,
CONSTRAINT [PK_a] PRIMARY KEY CLUSTERED([aID] ASC)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]
GO
CREATE TABLE [dbo].[b]([bID] [int] IDENTITY(1,1) NOT NULL,[aID] [int] NOT NULL, [bCode] [varchar](20) NOT NULL,
CONSTRAINT [PK_b] PRIMARY KEY CLUSTERED([bID] ASC)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]
GO
CREATE TABLE [dbo].[c]([cID] [int] IDENTITY(1,1) NOT NULL,[bID] [int] NOT NULL,[cCode] [varchar](20) NOT NULL,
CONSTRAINT [PK_c] PRIMARY KEY CLUSTERED([cID] ASC)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]
GO
ALTER TABLE [dbo].[b] WITH CHECK ADD CONSTRAINT [FK_b_a] FOREIGN KEY([aID])
REFERENCES [dbo].[a] ([aID])
GO
ALTER TABLE [dbo].[b] CHECK CONSTRAINT [FK_b_a]
GO
ALTER TABLE [dbo].[c] WITH CHECK ADD CONSTRAINT [FK_c_b] FOREIGN KEY([bID])
REFERENCES [dbo].[b] ([bID])
GO
ALTER TABLE [dbo].[c] CHECK CONSTRAINT [FK_c_b]
GO
How do I create a CONSTRAINT that enforces a unique condition for a.aID, c.cCode?
If you are looking for a unique constraint over a combination of columns a.aID, c.cCode one way is to alter table c and add [aid] column to it and have a composite unique key.
ALTER TABLE [dbo].[c](
[cID] [int] IDENTITY(1,1) NOT NULL,
[bID] [int] NOT NULL,[cCode] [varchar](20) NOT NULL,
[cCode] [varchar](20) NOT NULL,
[aID] INT FOREIGN KEY REFERENCES [a]([aID]) NOT NULL,
CONSTRAINT uq_cCode_aid UNIQUE NONCLUSTERED (cCode,aID),
CONSTRAINT [PK_c] PRIMARY KEY CLUSTERED([cID] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON
[PRIMARY]) ON [PRIMARY]
GO
You can add a unique constraint as follows:
ALTER TABLE [C] ADD CONSTRAINT [uc_C_cCode] UNIQUE NONCLUSTERED [cCode];
You cannot however enforce a constraint across tables, which is what it sounds like you are trying to do.
As for table A.aID, its a primary key, it will already have a unique constraint.
I found a way to get what I wanted (I think) using an indexed view. Please comment on if this seems appropriate. My tests so far conclude that it does work.
I created a view with schemabinding on joining c to a (going through b).
I created an clustered index to enforce unique on aID and cCode.
This allows me to not need to include aID within the c table but still enforces the unique constraint.
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE VIEW [dbo].[vw.aIDcCode] WITH SCHEMABINDING
AS
SELECT dbo.a.aID, dbo.c.cCode
FROM dbo.a
INNER JOIN
dbo.b ON dbo.a.aID = dbo.b.aID
INNER JOIN
dbo.c ON dbo.b.bID = dbo.c.bID
GO
SET ARITHABORT ON
GO
SET CONCAT_NULL_YIELDS_NULL ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_NULLS ON
GO
SET ANSI_PADDING ON
GO
SET ANSI_WARNINGS ON
GO
SET NUMERIC_ROUNDABORT OFF
GO
CREATE UNIQUE CLUSTERED INDEX [IDX_Unique_aIDcCode] ON [dbo].[vw.aIDcCode]
([aID] ASC, [cCode] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY]
GO

tsql default value dpends on other field

is something like that possible ?
CREATE TABLE [dbo].[T_ALERT](
[id] [bigint] NOT NULL IDENTITY(1,1),
[times] [int] NOT NULL DEFAULT(1),
[times left] [int] DEFAULT(times), --Here times_left get times as default
CONSTRAINT [PK_T_ALERT] PRIMARY KEY CLUSTERED
(
[user_id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
No, but you can accomplish the same thing by making the column TimesUsed (or whatever is appropriate for your usage) and defaulting it to 0, then just doing subtraction in your query.