Primary key value doesn't increment auto in Entity framwork database - c#

I am sure m missing something really small but i am having issue of Primary value auto incremental. I have creates two simple table and I have adopt Existing database model first approach by using Entity Framework 5. I simple adding values in table from console program.
My issue is code works fine for first time, but crashes if i try to add more value by running whole app again and i found the reason; the EF doesn't increment primary index automatically.
table
CREATE TABLE [dbo].[Book_Titles] (
[Book_ID] INT NOT NULL,
[Title] NVARCHAR (150) NOT NULL,
PRIMARY KEY CLUSTERED ([Book_ID] ASC)
);
CREATE TABLE [dbo].[Books_Authors] (
[Author_Id] INT NOT NULL,
[Author_Name] NVARCHAR (150) NOT NULL,
[Book_ID] INT NULL,
PRIMARY KEY CLUSTERED ([Author_Id] ASC),
FOREIGN KEY ([Book_ID]) REFERENCES [dbo].[Book_Titles] ([Book_ID])
);
Console program
namespace Database_First_01
{
class Program
{
static void Main(string[] args)
{
using (var db = new BooksContext())
{
var book = new Book_Titles()
{
Title ="EF ",
};
var author = new Books_Authors()
{
Author_Name = "me!",
};
book.Books_Authors.Add(author);
db.Book_Titles.Add(book);
db.SaveChanges();
}
}
}
}
many thanks in advance.

Try this
CREATE TABLE [dbo].[Book_Titles] (
[Book_ID] INT IDENTITY(1,1) NOT NULL,
[Title] NVARCHAR (150) NOT NULL,
PRIMARY KEY CLUSTERED ([Book_ID] ASC)
);
Define Identity on Column
Same as other if you want.

Microsoft SQL Server uses the IDENTITY keyword to perform an auto-increment feature. and its missing in your case.
You can use IDENTITY property in different cases
Its used with the CREATE TABLE
and ALTER TABLE Transact-SQL statements.
so if you have already created the table ( and it has data ) you may just alter like as follow.
ALTER TABLE (yourTable) ADD NewColumn INT IDENTITY(1,1)
ALTER TABLE (yourTable) DROP COLUMN OldColumnName
sp_rename 'yourTable.NewColumn', 'OldColumnName', 'COLUMN'
and it will save your data in the existing table.
Hope it will help

Related

Setting up tables in Dapper

I'm new to Dapper and currently I'm trying to populate my fresh database.
Since Dapper has no ability to create a table from model directly, how should I populate my database? Are there any good practices other than executing a schema from the variable?
Currently, I'm using this (dirty approach):
public void CreateTables()
{
using (var connection = GetSQLiteHandle())
{
string sql = #"
CREATE TABLE IF NOT EXISTS statistics (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
name TEXT NOT NULL,
value TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS posts (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
content TEXT NOT NULL,
created TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS names (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
name TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
username TEXT NOT NULL,
email TEXT NOT NULL,
created TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS storage (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
key TEXT NOT NULL,
value TEXT NOT NULL
);
";
connection.Execute(sql);
}
}
Dapper has no ability to generate tables like Entity Framework. Hence, you may use EF with code first approach. If you want to use Dapper, you can use migrator tools such as fluent migrator and generate db with it.

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.

Retrieve and iterate data using JOIN in C# MVC4

I am not getting how to iterate data that is retrieved using join.
Table project images
[img_id] INT IDENTITY (1, 1) NOT NULL,
[proj_id] INT NOT NULL,
[path] NVARCHAR (50) NOT NULL,
PRIMARY KEY CLUSTERED ([img_id] ASC),
CONSTRAINT [FK_projimg_projects] FOREIGN KEY ([proj_id]) REFERENCES [dbo].[Projects] ([proj_id])
Table Projects
[proj_id] INT IDENTITY (1, 1) NOT NULL,
[proj_name] NVARCHAR (50) NOT NULL,
[step1] NVARCHAR (MAX) NOT NULL,
[step2] NVARCHAR (MAX) NOT NULL,
[step3] NVARCHAR (MAX) NOT NULL,
[step4] NVARCHAR (MAX) NOT NULL,
[user_id] INT NOT NULL,
[materials] NVARCHAR (MAX) NOT NULL,
[tag] NVARCHAR (50) NOT NULL,
PRIMARY KEY CLUSTERED ([proj_id] ASC),
CONSTRAINT [FK_Projects_user] FOREIGN KEY ([user_id]) REFERENCES [dbo].[Users] ([user_id])
i retrieved the data using following query
var tutorial = from proj in de.Projects
join image in de.projimgs
on proj.proj_id equals image.proj_id
select new {
proj.proj_name,
proj.materials,
proj.step1,
proj.step2,
proj.step3,
proj.step4,
image.path,
};
and now i want to iterate the data, each project containing multiple images, how do i show those images in single iteration of foreach loop. Can anyone help clearly.
Thankx in advance.
Well you can iterate then in two foreach loop like
foreach(project p in tutorial)
{
foreach(image in p.Images)
{
//Do your processing
}
}
First, if you have your foreign keys set up as mapped properties, Rahul's answer is the easiest. If you actually need to do a join, your query isn't quite right.
Keep in mind what your SQL statement is doing. When you do an INNER JOIN, you're asking for one result per combination of values. Your query is equivalent (roughly) to:
SELECT proj.proj_name, proj.proj_name, proj.materials, proj.step1, proj.step2, proj.step3, proj.step4, image.path
FROM Project proj
INNER JOIN Project_Images image ON image.ProjectId = proj.Id
Given your select statement, you will get back multiple copies of the project - one for each image. You just loop over those results.
It sounds like what you wrote is incorrect and what you actually want is a group by:
var tutorial = from proj in de.Projects
join image in de.projimgs on proj.proj_id equals image.proj_id
group image by proj into groupedImages
select new { Project = groupedImages.Key, Images = groupedImages };
Then you loop over it:
foreach (var project in tutorial)
{
// Do what you want with project here
foreach (var image in project.Images)
{
// Do what you want with image here
}
}

EntityFramework 6 AddOrUpdate not working with compound or composite primary key

The issue has been my weekend nightmare... I have a table where AddOrUpdate is not working correctly, it keeps adding but never updating.
All I want to do is when I add a new entity to the table using AddOrUpdate I want it to check the AppointmentId and CompletionCodeId columns and if they match than update, otherwise add.
Table structure:
CREATE TABLE [dbo].[AppointmentCodes] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[AppointmentId] INT NOT NULL,
[Quantity] INT NOT NULL,
[CompletionCodeId] INT NOT NULL,
CONSTRAINT [PK_AppointmentCodes] PRIMARY KEY CLUSTERED ([Id] ASC, [AppointmentId] ASC));
^^ Not sure if that is even correct.
public void AddOrUpdate(T entity)
{
//uses DbContextExtensions to check value of primary key
_context.AddOrUpdate(entity);
Commit();
}
METHOD
public void AddAppointmentCodes(List<AppointmentCode> appointmentCodes)
{
appointmentCodes.ForEach(x => _appointmentCodeRepository.AddOrUpdate(x));
}
You missed this overload of AddOrUpdate:
_context.AppointmentCodes
.AddOrUpdate(a => new { a.AppointmentId, a.CompletionCodeId },
appointmentCodes.ToArray());

How to insert a new record which has a auto increment number as primary key?

For example, I have the following Table:
CustomerInfo
cus_id: auto increment, int, is Identity
cus_name: nvarchar
If I use the follow codes to insert the record "Peter",
string name = "Peter";
DataContext DC = new DataContext();
CustomerInfo newCustomer = new CustomerInfo();
newCustomer.cus_name = name;
DC.CustomerInfos.InsertOnSubmit(newCustomer);
DC.SubmitChanges();
The following error returns,
Can't perform Create, Update, or Delete operations on 'Table(CustomerInfo)' because it has no primary key.
Do I need to self-define the cus_id or any other solutions? Thanks!
First of all LINQ-To-SQL needs primary keys in order to be able to do Inserts and Updates, so you probably have to add the Primary Key in your table.
Now, because it is an auto incremented identity column, in your dbml, you have to select the column "cus_id" of the "CustomerInfo" table and go to the properties and set the following:
Auto Generated Value : True
Auto-Sync : OnInsert
This will ensure that when you insert a new row it will get a new id.
naratting from answer 1 of question you'll have to make cus_id as primary key too.
you can also try to do following
CREATE TABLE Customers
(
cus_id int NOT NULL AUTO_INCREMENT,
cus_name varchar(255) NOT NULL,
PRIMARY KEY (cus_id)
)
I got this error to. As far as I manged to fix it was to add a primary key.
This code made me a primary key and made it autoincrement. Maybe it's what you are looking for?
(When you create the table)
columnname bigint IDENTITY(1,1) NOT NULL,
CONSTRAINT pkcolumnname PRIMARY KEY CLUSTERED

Categories

Resources