How to get Identity insert to work with my model - c#

I am trying to allow users to create objects "Rooms". They will be able to add items to the room, and delete and create rooms for their account.
I have my table set up like this,
CREATE TABLE [dbo].[Rooms](
[Value] [money] NULL,
[Name] [nvarchar](50) NOT NULL,
[RoomID] [int] PRIMARY KEY IDENTITY(1,1) NOT NULL,
[User] [nvarchar](128) NOT NULL)
And my insert code like this,
[HttpPost]
public async Task<ActionResult> Create([Bind(Include = "Name, User,
RoomID")] Room room)
{
if (ModelState.IsValid)
{
using (var transaction = db.Database.BeginTransaction())
{
db.Database.ExecuteSqlCommand("SET IDENTITY_INSERT Rooms ON");
room.User = User.Identity.GetUserId();
db.Rooms.Add(room);
await db.SaveChangesAsync();
db.Database.ExecuteSqlCommand("SET IDENTITY_INSERT Rooms OFF");
transaction.Commit();
}
return RedirectToAction("Index");
}
return View(room);
}
Whenever I try adding an object room to my database, I leave the RoomID undefined. I expect the database to automatically increment the ID, but it is throwing an error....
Violation of PRIMARY KEY constraint 'PK__Rooms__328639191EFADF47'. Cannot insert duplicate key in object 'dbo.Rooms'. The duplicate key value is (0).
The statement has been terminated.
It is setting the value of RoomID to 0 everytime.

Related

One to One relation in Entity frame work Insert

I have 2 tables, Users and Employees
CREATE TABLE [dbo].[Users](
[UserID] [int] IDENTITY NOT NULL,
[Username] [nvarchar](8) NOT NULL,
[Activo] [bit] NOT NULL,
[UltimoAcesso] [datetime] NULL,
PRIMARY KEY (UserID)
)
CREATE TABLE [dbo].[Employees](
[ColaboradorID] [int] IDENTITY(1,1) NOT NULL,
[Nome] [nvarchar](100) NOT NULL,
[Email] [nvarchar](100) NULL,
[UserID] [int] NULL
PRIMARY KEY(ColaboradorID),
UNIQUE (UserID)
)
ALTER TABLE [dbo].[Employees] WITH CHECK ADD CONSTRAINT [FK_Employees_UtilizadorID] FOREIGN KEY([UserID])
REFERENCES [dbo].[Users] ([UserID])
ON UPDATE CASCADE
ON DELETE CASCADE
I'm using Entity FrameWork Database first.
I'm trying to insert a new user
public void fvAddUser_InsertItem()
{
var item = new InventarioCiclico.Users();
using (InventarioCiclicoContext db = new InventarioCiclicoContext())
{
Employee c = new Employee ();
c.Nome = (fvAddUser.FindControl("txtNome") as TextBox).Text;
c.Email = (fvAddUser.FindControl("txtEmail") as TextBox).Text;
item.Employee.Add(c);
var employee = db.Set<Employee>();
TryUpdateModel(item);
if (ModelState.IsValid)
{
if (db.Users.Any(u => u.Username == item.Username))
{
// Handle exception
}
else
{
db.Users.Add(item);
db.SaveChanges();
var userID = item.UserID;
c.UserID = userID;
employee.Add(c);
db.SaveChanges();
}
}
}
}
However it keeps giving me exception of violation of unique value? Before starting with entity framework I would insert on Users table first, get scope_identity and insert on Employee table after and I'm trying to do this using EF6 but i don't know what can i do about this.
You are adding two employees with the same UserId in the database and since UserId is a unique field in employee table you are getting the exception of violation of unique value.
In the line item.Employee.Add(c); you are add the employee to the user, therefore, when adding the user to the database, the employee will be added two. So you don't need the last three lines:
c.UserID = userID;
employee.Add(c);
db.SaveChanges();

System.Data.SqlClient.SqlException: 'The INSERT statement conflicted with the FOREIGN KEY constraint

I'm still getting this error during debug. I'm not sure what to do, because I have added the AdddressID for the Person klass.
Please help!
The INSERT statement conflicted with the FOREIGN KEY constraint \"FK_Person_ToAddress\". The conflict occurred in database \"DirectoryDatabase\", table \"dbo.Address\", column 'AddressID'
The functions that throws this error is:
public void CreatePersonDB(ref Person person)
{
string CreatePerson =
#"INSERT INTO [Person] (FirstName, MiddleName, LastName, AddressID)
OUTPUT INSERTED.PersonID
VALUES (#FName, #MName, #LName, #AID)";
using (SqlCommand cmd = new SqlCommand(CreatePerson, OpenConnection))
{
// Get your parameters ready
cmd.Parameters.AddWithValue("#FName", person.FirstName);
cmd.Parameters.AddWithValue("#MName", person.MiddleName);
cmd.Parameters.AddWithValue("#LName", person.LastName);
cmd.Parameters.AddWithValue("#AID", person.PrimaryAddress.AddressID);
try
{
person.PersonID = (int)cmd.ExecuteScalar(); //Returns the identity of the new tuple/record}
}
catch
{
Console.WriteLine("Adresse ID doesn't exist, do you want to add it? [y/n]");
ConsoleKeyInfo input = Console.ReadKey();
if (input.Key == ConsoleKey.Y)
{
//create an insert query to the dbo.Adresse the same way you did with the dbo.person.
CreateAddressDB();
}
}
}
The database sql code for Person & Address looks like this (after editing):
CREATE TABLE Address (
AddressID BIGINT IDENTITY(1,1) NOT NULL,
StreetName NVARCHAR(MAX) NOT NULL,
HouseNumber NVARCHAR(MAX) NOT NULL,
CityID BIGINT NOT NULL,
[PersonID] NCHAR(10) NOT NULL,
[PrimaryAddress] INT NOT NULL,
CONSTRAINT pk_Address PRIMARY KEY CLUSTERED (AddressID),
CONSTRAINT fk_Address FOREIGN KEY (CityID)
REFERENCES City (CityID)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
This is for the Address table:
CREATE TABLE Person (
PersonID BIGINT IDENTITY(1,1) NOT NULL,
FirstName VARCHAR(50) NOT NULL,
MiddleName NVARCHAR(50) NOT NULL,
LastName NVARCHAR(50) NOT NULL,
AddressID BIGINT NOT NULL,
CONSTRAINT pk_Person PRIMARY KEY CLUSTERED (PersonID),
CONSTRAINT fk_Person FOREIGN KEY (AddressID)
REFERENCES Address (AddressID)
)
In table dbo.Address doesn`t exists record with your person.PrimaryAddress.AddressID value
Your are trying to insert an AdresseID to the person table that doesn't exist in the Adresse table.
Try this instead:
public void CreatePersonDB(ref Person person)
{
string CreatePerson =
#"INSERT INTO [Person] (FirstName, MiddleName, LastName, AddressID)
OUTPUT INSERTED.PersonID
VALUES (#FName, #MName, #LName, #AID)";
using (SqlCommand cmd = new SqlCommand(CreatePerson, OpenConnection))
{
// Get your parameters ready
cmd.Parameters.AddWithValue("#FName", person.FirstName);
cmd.Parameters.AddWithValue("#MName", person.MiddleName);
cmd.Parameters.AddWithValue("#LName", person.LastName);
cmd.Parameters.AddWithValue("#AID", person.PrimaryAddress.AddressID);
try()
{
person.PersonID = (int)cmd.ExecuteScalar(); // Returns the identity of the new tuple/record}
catch()
{
DialogResult dialogResult = MessageBox.Show("Adresse ID doesn't exist, do you want to add it?", "Alerte",MessageBoxButtons.YesNo);
if(dialogResult == DialogResult.Yes)
{
// create an insert query to the dbo.Adresse the same way you did with the dbo.person.
}
}
}
}

Insert Data using entity framemodel

I am a student and working on a college project.
I have created a simple scenario which I am facing in my project.
The simple database looks like this.
**Location Table**
CREATE TABLE [dbo].[Location] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[longitude] VARCHAR (50) NULL,
[latitude] VARCHAR (50) NULL,
PRIMARY KEY CLUSTERED ([Id] ASC)
);
**Role Table**
CREATE TABLE [dbo].[Role] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[Name] VARCHAR (50) NULL,
PRIMARY KEY CLUSTERED ([Id] ASC)
);
**Another table**
CREATE TABLE [dbo].[Another] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[Anything] VARCHAR (50) NULL,
PRIMARY KEY CLUSTERED ([Id] ASC)
);
**User Table**
CREATE TABLE [dbo].[User] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[name] VARCHAR (50) NULL,
[address] VARCHAR (50) NULL,
[loc_id] INT NOT NULL,
[role_id] INT NOT NULL,
[another_id] INT NOT NULL,
PRIMARY KEY CLUSTERED ([Id] ASC),
CONSTRAINT [FK_User_lococation] FOREIGN KEY ([loc_id]) REFERENCES [dbo].[Location] ([Id]),
CONSTRAINT [FK_User_another] FOREIGN KEY ([another_id]) REFERENCES [dbo].[Another] ([Id]),
CONSTRAINT [FK_User_role] FOREIGN KEY ([role_id]) REFERENCES [dbo].[Role] ([Id])
);
I have populated Role table with following values
enter image description here
Now I want to add user using EntityFrameWorkCore
My controller looks like this
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Id,Name,Address,RoleId")] User user)
{
if (ModelState.IsValid)
{
_context.Add(user);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
ViewData["LocId"] = new SelectList(_context.Location, "Id", "Id", user.LocId);
ViewData["RoleId"] = new SelectList(_context.Role, "Id", "Id", user.RoleId);
return View(user);
}
The problem is I want to Add User but it doesn't have a foreign key of Location table and Another table.
How can I create a Location_id and Another_id and put in User
I want my User object to get the foreign key of location table and another table.
Please help me, I don't know how to do that it will great help for me.Thanks
If you don't have info about FK, don't generate it randomly, make foreign key column nullable in class user. Surely, when you are using EF you have navigation properties in User class. You can add also int property which stores id of associated entity (this is advised, so if you don't have, create such property). Type of this property should (obviously) nullable, so use int?. Then update database, so FK column in DB will be also nullable. Then you will be able to insert user entity.

Set value of a column in INSTEAD OF INSERT

I have two forms namely frmSupplier and frmCustomer that allows user to add and update Customer and Supplier information. Currently we have a two table in a SQL Server database for Customer and Supplier. We are migrating the two tables into one called Contact and converted the Customer and Supplier table to a view. We did this because we want that the code in our application will no longer be modified since this will take time.
I do researched and found out INSTEAD OF INSERT triggers.
This is the SQL:
CREATE TABLE [dbo].[Contact]
(
[ContactID] [int] IDENTITY(1,1) NOT NULL,
[Code] [varchar](20) NULL,
[ContactName] [varchar](52) NULL,
[Active] [bit] NULL,
[Customer] [bit] NULL,
[Supplier] [bit] NULL,
[DeliveryAddr1] [varchar](255) NULL,
[DeliveryAddr2] [varchar](75) NULL,
[DeliveryAddr3] [varchar](75) NULL,
[DeliveryAddr4] [varchar](75) NULL,
[CreateDate] [datetime] NULL,
[LastUpdated] [datetime] NULL,
[TempID] [int] NULL,
CONSTRAINT [PK_Contact]
PRIMARY KEY CLUSTERED ([ContactID] ASC)
) ON [PRIMARY]
GO
Creating view for customers:
CREATE VIEW [dbo].[Customer]
AS
SELECT
ContactID AS CustID, Code AS CustCode,
ContactName AS CustName, Active, Customer,
DeliveryAddr1, DeliveryAddr2, DeliveryAddr3, DeliveryAddr4,
CreateDate, LastUpdated
FROM
dbo.Contact
WHERE
(Customer = 1)
GO
View for suppliers:
CREATE VIEW [dbo].[Supplier]
AS
SELECT
ContactID AS SuppID, Code AS SuppCode,
ContactName AS SuppName, Active,
DeliveryAddr1, DeliveryAddr2, DeliveryAddr3, DeliveryAddr4,
CreateDate, LastUpdated
FROM
dbo.Contact
WHERE
(Supplier = 1)
I want that when a supplier is inserted, it will insert it to Contact and set Supplier=1 or if a customer is inserted, it will set Customer=1.
This is my trigger:
CREATE TRIGGER trgNewCust
ON dbo.Contact
INSTEAD OF INSERT
AS
BEGIN
INSERT INTO Customer
SELECT
[CustCode], [CustName], [Active],
[DeliveryAddr1], [DeliveryAddr2], [DeliveryAddr3], [DeliveryAddr4]
FROM
inserted
END
Where will I set the Customer=1 or Supplier=1? Another question is how will I know that the newly inserted item in the Contact is for supplier or customer?
Values are inserting in a C# application using INSERT INTO Customer... for customer and INSERT INTO Supplier... for supplier.
You need to have your INSTEAD OF INSERT triggers on the VIEWS - not the Contact table!
CREATE TRIGGER trgNewCust
ON dbo.Customer -- trigger must be on the VIEW - not the underlying table!
INSTEAD OF INSERT
AS
BEGIN
-- *ALWAYS* explicitly define the list of columns you're inserting into!
INSERT INTO Contact(Code, ContactName, Active, Customer, Supplier,
DeliveryAddr1, DeliveryAddr2, DeliveryAddr3, DeliveryAddr4)
SELECT
CustCode, CustName, Active, 1, 0,
DeliveryAddr1, DeliveryAddr2, DeliveryAddr3, DeliveryAddr4
FROM
inserted
END
So here, in your trigger on the Customer view, you set Customer=1, Supplier=0 - you apply the same trigger logic to the Supplier view and insert the data into the Contact table, setting Customer=0, Supplier=1
Now, from your code, if you "insert" something into the Customers view, a row in the dbo.Contact table will be created, and the same happens when you "insert" into the Supplier view.

DELETE statement conflicted (ASP.NET MVC)

I have ASP.NET MVC app
I have two relative tables Companies and Vacancies.
When I delete Company, I want to delete relative to it Vacancies.
Here is my controller
public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Company companies = db.Companies.Find(id);
if (companies == null)
{
return HttpNotFound();
}
return View(companies);
}
// POST: Companies/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
Company companies = db.Companies.Find(id);
db.Companies.Remove(companies);
db.SaveChanges();
return RedirectToAction("Index");
}
And here is Companies table
CREATE TABLE [dbo].[Companies] (
[CompanyID] INT IDENTITY (1, 1) NOT NULL,
[CompanyName] NVARCHAR (MAX) NULL,
PRIMARY KEY CLUSTERED ([CompanyID] ASC)
);
AnŠ² vacancies
CREATE TABLE [dbo].[Vacancies] (
[VacancyId] INT IDENTITY (1, 1) NOT NULL,
[VacancyName] NCHAR (10) NULL,
[CompanyID] INT NULL,
PRIMARY KEY CLUSTERED ([VacancyId] ASC),
CONSTRAINT [FK_Vacancies_ToTable] FOREIGN KEY ([CompanyID]) REFERENCES [dbo].[Companies] ([CompanyID])
);
How I need to modify my syntax to easily delete company?
Modify your dependent to add ON DELETE CASCADE
CREATE TABLE [dbo].[Vacancies] (
[VacancyId] INT IDENTITY (1, 1) NOT NULL,
[VacancyName] NCHAR (10) NULL,
[CompanyID] INT NULL,
PRIMARY KEY CLUSTERED ([VacancyId] ASC),
CONSTRAINT [FK_Vacancies_ToTable]
FOREIGN KEY ([CompanyID])
REFERENCES [dbo].[Companies] ([CompanyID])
ON DELETE CASCADE);
This will allow delete your references when you delete you're company.
Alternatively you can mark each entity as deleted from C#, this will give you more control and avoid accidental deletes

Categories

Resources