Linq to Sql Datacontext primary key not set - c#

I created in my application a dataclasses context and want to insert in my database some entries via LINQ but it says
Can't perform Create, Update, or Delete operations on
'Table(discipline)' because it has no primary key.
But I already marked a column in the designer as identity column to true;
Can anyone please help?

Setting a column as IDENTITY doesn't mean that it is also the PRIMARY KEY of your table.
You need to set it explicitily using SSMS interface of through a sql statement
You can set it when creating the table:
CREATE TABLE Nations
(
NationID int IDENTITY(1,1),
Name varchar(255) NOT NULL,
CapitalCity varchar(255)
PRIMARY KEY (NationID)
)
or using the ALTER TABLE statement
ALTER TABLE Nations ADD PRIMARY KEY (NationID)

Related

Microsoft Sync Framework unique index error

I use the MS Sync Framework to sync my SQL Server instance with a local SQL CE file to make it possible working offline with my Windows app.
I use GUIDs as keys. On my table I have a unique index on 2 columns: user_id and setting_id:
usersettings table
------------------
id PK -> I also tried it without this column. Same result
user_id FK
setting_id FK
value
Now I do the following:
I create a new record in this table in both databases - SQL Server and SQL CE with the same user_id and setting_id.
This should work and merge the data together since this can happen in real life. But I get an error when syncing saying the unique key constraint led to an error. The key pair already exists in the table.
A duplicate value cannot be inserted into a unique index. [ Table name = user_settings,Constraint name = unique_userid_settingid ]
Why can't MS sync handle that? It should not try to insert the key pair again. It should update the value if needed.
The issue is if you add the same key pair to different copies of the table, they get different IDs (GUIDs) as primary keys in this usersettings table.
As this is simply a many-to-many table between Users and Settings, there is no need to have that ID as a PK (or even a column at all).
Instead, just use a concatenated key of the two FKs e.g.,
CREATE TABLE [dbo].[usersettings](
[user_id] [UNIQUEIDENTIFIER] NOT NULL,
[setting_id] [UNIQUEIDENTIFIER] NOT NULL,
[value] [varchar](50) NOT NULL,
CONSTRAINT [PK_usersettings] PRIMARY KEY CLUSTERED ([user_id] ASC, [setting_id] ASC) );
Of course, include appropriate field settings (e.g., if you use VARCHARs to store the IDs) and relevant FKs.
As the rows inserted should now be identical on the two copies, it should merge fine.
If you must have a single column as a unique identifier for the table, you could make it meaningful e.g.,
the PK (ID) becomes a varchar (72)
it gets filled with CONCAT(user_ID, setting_id)
As the User_ID and Setting_ID are FKs, you should already have them generated so concatenating them should be easy enough.
Do you get the error during sync, then it should appear as a conflict, that you must solve in code.
https://learn.microsoft.com/en-us/previous-versions/sql/synchronization/sync-framework-2.0/bb734542(v=sql.105)
I also see this in the manual: By default, the following objects are not copied to the client database: FOREIGN KEY constraints, UNIQUE constraints, DEFAULT constraints, and the SQL Server ROWGUIDCOL property. This indicates poor support for your scenario
I suggest you remove the unique constraint from the device table.

How to make sequential id number in SQL Server start form 1 like in an MS Access database

When I use Microsoft SQL Server database and make a filed's data type as uniqueidentifier and use the function newid() or newsequentialid(), it makes a new id that contain 32 value (hexadecimal value).
However, I need a way to make an auto-increment values starts with number 1 and so on just like auto-increment fields in MS Access.
Then I want to add other values using a C# program while the SQL Server adds the auto-increment field automatically without errors.
Note: I'm using SQL Server 2014, and Visual Studio 2015 perf.
You can use SQL Server method IDENTITY(1,1) to increment a column by 1 and starts from 1.
CREATE TABLE [dbo].[XXX](
[ID] [int] IDENTITY(1,1))
If you want the IncrementId also to be the primary key you can create your table like:
CREATE TABLE [dbo].[SomeTable](
[IncrementId] [int] IDENTITY(1,1) NOT NULL,
[OtherColumn] [nvarchar](max) NOT NULL,
CONSTRAINT [PK_SomeTable] PRIMARY KEY CLUSTERED
(
[IncrementId] ASC
))
You than can insert values to the table like
INSERT INTO dbo.SomeTable (OtherColumn) VALUES ('SomeValue')
And this will give you a new row with an id that is the next in line so to speak
Create a Column and make it an identity column to the table
To create an identity column, you may use the Management Studio or u can write a query.
When Inserting data to the table, provide data to the columns, but not to the column created as identity column.
If you want to have an integer identity, you should use either TINYINT, SMALLINT, INT, or BIGINT column for your primary key. If you need GUID, you should use uniqueidentifier column type. You can't mix and match.
Regarding to the auto increment feature, if you need to insert a value manually, you should inactivate IDENTITY option on the table, insert your unique value, and then activate it again. I'm not really sure if it's a good idea to do this, but this is how it works:
-- Allows you to insert a value into identity column.
SET IDENTITY_INSERT [SchemaName].[TableName] ON;
-- Do you insertion here...
-- Deactivates the identity value insertion.
SET IDENTITY_INSERT [SchemaName].[TableName] OFF;

How to make deleted record as false on the table in SQL Server using c#?

I have a ward table and it contains columns like wardid, wmemname, isActive, and so on... wardid is the primary key and isActive is boolean.
If the user deletes the record from the front end, I set isActive to false.
"Record is deleted successfully"
This message is shown to the user.
In my delete procedure I wrote an update statement to make isActive set to false:
update wardtable
set isActive = false
where wardid = #wardid
Fine up to here. In case the user wants to enter the details with the deleted wardid, now there is a problem with a primary key violation message from the front end when he tries to enter the data with the deleted wardid.
How to solve this issue?
Suppose if I take another id in my ward table then, it allows if I make id as an autoincrement. But duplicate wardid's are allowed in my ward table if I do like that.
So, what is the best way to do this?
Your doing too much with your primary key.
Create a real primary key of type uniqueidentifier / long and auto generated if need be.
Wardid should NOT be your primary key for this table, use your business logic to lookup data on this column and update / delete / insert as required. leave the new primary key for use by your database only. If wardid needs to be unique, make it a unique column by adding it to a unique index or use business logic.
To add on to uk2k05's answer an example of how you would implment it would be
CREATE TABLE dbo.wardtable
(
wardTableId bigint NOT NULL IDENTITY (1, 1),
wardid int NOT NULL,
deletedUniqueifier uniqueidentifier NOT NULL default('00000000-0000-0000-0000-000000000000'),
wmemname varchar(50) NOT NULL,
isActive AS (case when deletedUniqueifier = '00000000-0000-0000-0000-000000000000' then 1 else 0 end) PERSISTED
)
ALTER TABLE dbo.wardtable ADD CONSTRAINT
PK_wardtable PRIMARY KEY CLUSTERED (wardTableId)
CREATE UNIQUE NONCLUSTERED INDEX UX_wardtable_wardid
ON dbo.wardtable (wardid, deletedUniqueifier)
Now that isActive is a computed column your update would also have to change to
update wardtable
set deletedUniqueifier = newid()
where wardid = #wardid and deletedUniqueifier = '00000000-0000-0000-0000-000000000000'
One other logical change you will need to do, any forgen keys that link to this table should link using wardTableId instead of wardid

Change SQL Server primary key using C#

I need to change a column type in a SQL Server table.
I need do it using a script or C#.
The original datatype is integer and the new type is varchar(50).
I can do it using this SQL script:
ALTER TABLE confezionamento ALTER COLUMN partnumber varchar(50)
but the problem is that this column is in a set of primary keys.
When I try do execute, an error occurred because PK_CONFEZIONAMENTO is using the column.
How I can do it without access to SQL Server Management Studio?
You will need to run SQL Commands to do the following steps:
Drop primary key constraint
Alter primary key
Add primary key constraint
If there are any foreign keys or indexes, you may have to deal with them as well.
The commands you are looking for will be similar to these:
Alter table confezionamento drop constraint PK_CONFEZIONAMENTO
ALTER TABLE confezionamento ALTER COLUMN partnumber varchar(50)
ALTER TABLE confezionamento ADD CONSTRAINT PK_CONFEZIONAMENTO PRIMARY KEY (partnumber)
These commands can all be sent from C# using ADO.Net or similar methods.

Insert values in both related tables MySQL

I have two tables:
create table `db_csms`.`tbl_item_requester`
(
`id` int not null,
`item_id` int not null,
`requester_id` int not null,
foreign key(`item_id`) references `db_csms`.`tbl_items`(`item_id`),
foreign key(`requester_id`) references `db_csms`.`tbl_user_details`(`user_id`),
primary key (`id`)
);
create table `db_csms`.`tbl_item_requests`
(
`id` int not null,
`item_requester_id` int not null,
`quantity` int(5) not null default 0,
foreign key(`item_requester_id`) references `db_csms`.`tbl_item_requester`(`id`),
primary key (`id`)
);
tbl_items and tbl_user_details are already populated with values. My problem is when a new row is added into table 1 because the table 2 uses the id of that new row inserted in table 1.
My issues are:
How to get the newly inserted row id of table 1 which is needed for inserting in table 2.
Strategy to solve this issue(my thinking):
Remove auto_increment and then generate a random value (using C# code) and use that value in both tables.
Are there any workaround to this problem? Do i have to change my strategy? Is the Database design incorrect?
Since you're using MySQL as your database, there is the specific function LAST_INSERT_ID()
which only works on the current connection that did the insert.
In case of SQL Server you could write:
Insert .... Values(....); Select Scope_Identity()
and use SqlCommand.ExecuteScalar() that returns the first value of the first row, which would be the ID of newly inserted row. In MySql, you should be able to write last_insert_id() instead of Scope_identity().

Categories

Resources