Entering keys manually with Entity Framework - c#

I'm trying to use Entity Framework code first for a simple database project and I run into a problem I simply cannot figure out.
I noticed EF was setting the ID for my tables automatically increasing by 1 each time, completely ignoring the value I entered manually for that field. After some searching it is my understanding that the right way to disable this behavior is doing:
modelBuilder.Entity<Event>().Property(e => e.EventID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
However now I'm just getting this error and I have no idea why:
Unhandled Exception:
System.Data.Entity.Infrastructure.DbUpdateException: An error
occurred while updating the entries. See the inner exception for
details. ---
System.Data.UpdateException: An error occurred while updating the entries. See the inner exception for details. --->
System.Data.SqlClient.SqlException: Cannot insert explicit value for
identity column in table 'Events' when IDENTITY_INSERT is set to OFF.
If it's helpful, here is the POCO class in question:
public class Event
{
[Key, Required]
public int EventID { get; set; }
public string EventType { get; set; } //TODO: Event Type Table later on
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public virtual ICollection<Match> Matches { get; set; }
public virtual ICollection<EventParticipation> EventParticipation { get; set; }
}
Thanks in advance.

Since I prefer attributes, here the alternative for the sake of completeness:
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int Id { get; set; }
Note: This works also in EF Core.

By default Entity Framework assumes that an integer primary key is database generated (equivalent to adding the attribute HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity) or calling Property(e => e.EventID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); in the Fluent API.
If you look at the migration that creates the table you should see this:
CreateTable(
"dbo.Events",
c => new
{
EventID = c.Int(nullable: false, identity: true),
//etc
})
.PrimaryKey(t => t.EventID );
Then you changed the model using the Fluent API to DatabaseGenerated.None. EF puts this in the migration:
AlterColumn("dbo.Events", "EventID", c => c.Int(nullable: false, identity: false))
And the sql generated is this:
ALTER TABLE [dbo].[Events] ALTER COLUMN [EventID] [int] NOT NULL
Which actually does diddly squat. Dropping the IDENTITY from a column is not trivial. You need to drop and recreate the table or create a new column, then you have to copy the data and fix up foreign keys. So it's not surprising that EF isn't doing that for you.
You need to work out how best to do it for yourself. You could roll back your migrations to 0 and re-scaffold from scratch now that you have specified DatabaseGeneratedOption.None, or you could change the migration manually to drop and recreate the table.
Or you could drop and recreate the column:
DropColumn("Customer", "CustomerId");
AddColumn("Customer", "CustomerId", c => c.Long(nullable: false, identity: false));
EDIT
Or you could Switch Identity On/Off With A Custom Migration Operation

Related

Change type of id on column which is also a primary key with a ef migration

I have the following model:
[Key]
public int CustomerSearchConfigId { get; set; }
[Key]
public string CategoryId { get; set; }
[ForeignKey(nameof(CustomerSearchConfigId))]
public CustomerSearchConfig Config { get; set; }
CategoryId is a string, but I have now found out it would need to be an INT.
So I changed the type to an int, ran
dotnet ef migrations add AddFieldsAndRenameFields
Which produced among other this:
migrationBuilder.AlterColumn<int>(
name: "CategoryId",
table: "CustomerSearchConfigTagCategory",
type: "int",
nullable: false,
oldClrType: typeof(string),
oldType: "nvarchar(450)");
But when I run it, I get the following error:
The object 'PK_CustomerSearchConfigTagCategory' is dependent on column 'CategoryId'.
ALTER TABLE ALTER COLUMN CategoryId failed because one or more objects access this column.
When I search around for it, everyone seems to suggest I just delete it all and start over with a completely new migration history and everything..
Which is not an option!
So, does anybody know how I can change the type of CategoryId to an int without having to nuke my tables, migration, data and sanity?
The simple way is to delete the database and build it up again in case you don't have any impairment records.
So if you need to keep all of your information in the database see this guidе
https://www.codeproject.com/Articles/1193009/Changing-primary-key-data-type-in-EF-Core

Can you remove Identity from a primary key with Entity Framework 6?

I created a table via entity framework code-first with a primary key set to auto increment, but now I want to remove that auto-incrementing from the column. I've tried doing that with both fluent API:
public class ProductTypeMap: EntityTypeConfiguration<ProductType>
{
public ProductTypeMap()
{
// This is an enum effectively, so we need fixed IDs
Property(x => x.ProductTypeId)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
}
}
And an annotation:
public class ProductType
{
[Required, Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
public int ProductTypeId { get; set; }
public string ProductTypeName { get; set; }
}
And in both cases they produce the same migration code:
public partial class removeproducttypeidentity : DbMigration
{
public override void Up()
{
DropPrimaryKey("dbo.ProductTypes");
AlterColumn("dbo.ProductTypes", "ProductTypeId", c => c.Int(nullable: false));
AddPrimaryKey("dbo.ProductTypes", "ProductTypeId");
}
public override void Down()
{
DropPrimaryKey("dbo.ProductTypes");
AlterColumn("dbo.ProductTypes", "ProductTypeId", c => c.Int(nullable: false, identity: true));
AddPrimaryKey("dbo.ProductTypes", "ProductTypeId");
}
}
However, when I run that migration on the database, the Identity Specification is not removed from the SQL Server 2008 database table?
I also tried explicitly turning off the Identity in the migration as follows, but that didn't do it either:
AlterColumn("dbo.ProductTypes", "ProductTypeId", c => c.Int(nullable: false, identity: false));
Is there another way to tell SQL to remove the Identity?
As others have said, EF can't do this natively, although it will create a migration script that makes it look like it has. I've experimented with lots of ways of doing this and I find the easiest way is to:
Back up the database...
Change your class so it no longer has an identity in code (by removing the attribute or mapping)
Generate the migration with the Package Manager Console (add-migration [your migration name] )
Comment out the code in Up method in the newly generated migration
Add a new line of code ready to receive the SQL you'll generate below: Sql (#" ");
Go into SSMS and make sure it's set to generate scripts when you make a table change
Remove the identity in the table designer in SMSS
Save the table change in SSMS and copy the SQL generated. (That SQL makes a copy of the table with the data, drops the original table, then recreates the original table without the identity set on the column, then copies all the data back and adds all the foreign keys and constraints back on again)
Paste the SQL you just copied between the speech marks in the code you added above.
Run the migration
That should then give you a migration that removes the identity and can be run on other copies of the database successfully.
NB:The Down method that was generated won't work either because it will be adding the identity back on, which EF also can't do. If you need the Down method to work create a copy of the SQL you added and adjust it to create the table with the identity again.
The approach above is a quick way of what #Georg Patscheider describes so well in his answer.
If you want to remove identity, you need to
Step 1. And an annotation to the key column
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public short Id { get; set; }
this will generate the migration script
AlterColumn("dbo.TableName", "Id", c => c.Long(nullable: false));
But this script won't remove identity from the key column.
Step 2. manually remove identity from the key column in SQL Management Studio.
You don't need to back up the database.
If you get an error, you might need to go to "Tools"->"Options"->"Designers", and uncheck the "Prevent saving changes that require table re-creation"
You can not use ALTER COLUMN to set whether a column is an identity column (How to alter column to identity(1,1)).
Instead, you have to:
(backup DB)
CREATE TMP_table with columns of original table, but ID column set to identity: false
SET IDENTITY_INSERT [TMP_Table] ON
copy data from original to TMP table
SET IDENTITY_INSERT [TMP_Table] OFF
DROP original table
Rename TMP_table to original table name (EXECUTE sp_rename)
Tip: change the column in SQL Management Studio and inspect the emitted script (SQL SERVER – Add or Remove Identity Property on Column).
If you want to remove the Identity from a Primary Key, you’re going to need to Drop and Recreate the table and any associated Foreign Keys along with it.
Removing an identity specification from a column can only be done by re-creating the table. Look at the ALTER TABLE - ALTER COLUMN statement: there is no syntax to change (add or remove) an identity specification.
Refer flowing sites:
Cant remove identity attribute from PK
Entering keys manually with Entity Framework
EF6: Switching Identity On/Off with a Custom Migration Operation
Remove Identity from Primary Key with Drop and Recreate Table
Thanks to both of the answers explaining about what's involved in dropping the identity from the column I came up with a new version of the migration that achieves the removal of the identity from the PK column.
This solution loses all of the data in the table. This is acceptable in my case because the table in question is one that represents an enum and so is populated manually by my seed method (I was removing the identity in the first place so I could dictate the values used for the PK Id fields). Do not use this approach for user entered data!
public partial class removeproducttypeidentity : DbMigration
{
public override void Up()
{
DropForeignKey("dbo.Products", "ProductTypeId", "dbo.ProductTypes");
DropPrimaryKey("dbo.ProductTypes");
DropTable("dbo.ProductTypes");
CreateTable(
"dbo.ProductTypes",
c => new
{
ProductTypeId = c.Int(nullable: false),
ProductTypeName = c.String(),
})
.PrimaryKey(t => t.ProductTypeId);
AddForeignKey("dbo.Products", "ProductTypeId", "dbo.ProductTypes", "ProductTypeId");
}
public override void Down()
{
DropForeignKey("dbo.Products", "ProductTypeId", "dbo.ProductTypes");
DropPrimaryKey("dbo.ProductTypes");
DropTable("dbo.ProductTypes");
CreateTable(
"dbo.ProductTypes",
c => new
{
ProductTypeId = c.Int(nullable: false, identity: true),
ProductTypeName = c.String(),
})
.PrimaryKey(t => t.ProductTypeId);
AddForeignKey("dbo.Products", "ProductTypeId", "dbo.ProductTypes", "ProductTypeId");
}
}
This solution works well for when:
you can't lose data
recreating the table would take too long (e.g. you have millions of rows and copying would take a long time)
you want to handle everything with EF rather than writing custom migrations (the approach from #Georg Patscheider and #tomRedox go around EF)
which is a good idea because future migrations written by EF are less likely to have issues
(in my database, I have hundreds of migrations, some with custom SQL, which is causing me trouble years after those migrations were initially written because EF doesn't know about them!)
The solution
Create a new column and copy all the old IDs to it
Make the new column the primary key
Update all references to the old column to the new column
The setup
Example entities:
public class Foo
{
[Key]
public int Id { get; set; }
}
public class Bar
{
// This is the foreign key:
public int FooId { get; set; }
public virtual Foo Foo { get; set; }
}
Add a new property which has identity set to false
Change Foo to:
public class Foo
{
[Key]
public int Id { get; set; }
[Index(IsUnique = true)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int NewId { get; set; }
}
Generate a migration:
public partial class AddNewId : DbMigration
{
public override void Up()
{
AddColumn("dbo.Foos", "NewId", c => c.Int(nullable: false));
// This is a custom line which copies the data from the old column to the new.
Sql("UPDATE dbo.Foos SET NewId = Id");
CreateIndex("dbo.Foos", "NewId", unique: true);
}
public override void Down()
{
DropIndex("dbo.Foos", new[] { "NewId" });
DropColumn("dbo.Foos", "NewId");
}
}
Change references from Foo.Id to Foo.NewId
Here's the tricky part.
Any references to the Foo entity are still using the old Id property rather than the new NewId property.
Using Visual Studio:
Temporarily comment out the old Foo.Id property
Manually change the name of Foo.NumericId to Foo.Id (without updating references)
Rename Foo.Id back to Foo.NumericId but have VS also change all references
Comment back in the old Foo.Id property that was commented out in step 1
Make Foo.NewId the primary key
public class Foo
{
public int Id { get; set; }
[Key]
[Index(IsUnique = true)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int NewId { get; set; }
}
Update Bar.FooId
All entities now need to reference Foo.NewId instead of Foo.Id.
Change Bar:
public class Bar
{
// This is the foreign key:
public int FoodNewId { get; set; }
public virtual Foo Foo { get; set; }
}
Create a new migration:
public partial class AddNewIdPart2 : DbMigration
{
public override void Up()
{
DropForeignKey("dbo.Bars", "FooId", "dbo.Foos");
RenameColumn(table: "dbo.Bars", name: "FooId", newName: "FooNewId");
DropPrimaryKey("dbo.Foos");
AddPrimaryKey("dbo.Foos", "NewId");
AddForeignKey("dbo.Bars", "FooNewId", "dbo.Foos", "Newid");
}
public override void Down()
{
// ...
}
}
Done!
That should be everything.
You can now remove the old Foo.Id column if you want.

Auto-increment on partial primary key with Entity Framework Core

I have declared the following model using the EF Core fluent API:
modelBuilder.Entity<Foo>()
.HasKey(p => new { p.Name, p.Id });
Both fields are marked as the primary key when I create the database in PostgreSQL but the Id field is not marked as auto increment. I have also tried to add
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
to the Id field under Foo without it making any difference on the migration code. Is there a way to make the Id AI although it is a PPK?
Well those Data Annotations should do the trick, maybe is something related with the PostgreSQL Provider.
From EF Core documentation:
Depending on the database provider being used, values may be generated
client side by EF or in the database. If the value is generated by the
database, then EF may assign a temporary value when you add the entity
to the context. This temporary value will then be replaced by the
database generated value during SaveChanges.
You could also try with this Fluent Api configuration:
modelBuilder.Entity<Foo>()
.Property(f => f.Id)
.ValueGeneratedOnAdd();
But as I said earlier, I think this is something related with the DB provider. Try to add a new row to your DB and check later if was generated a value to the Id column.
First of all you should not merge the Fluent Api with the data annotation so I would suggest you to use one of the below:
make sure you have correclty set the keys
modelBuilder.Entity<Foo>()
.HasKey(p => new { p.Name, p.Id });
modelBuilder.Entity<Foo>().Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
OR you can achieve it using data annotation as well
public class Foo
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Key, Column(Order = 0)]
public int Id { get; set; }
[Key, Column(Order = 1)]
public string Name{ get; set; }
}
To anyone who came across this question who are using SQL Server Database and still having an exception thrown even after adding the following annotation on the int primary key
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
Please check your SQL, make sure your the primary key has 'IDENTITY(startValue, increment)' next to it,
CREATE TABLE [dbo].[User]
(
[Id] INT IDENTITY(1,1) NOT NULL PRIMARY KEY
)
This will make the database increments the id every time a new row is added, with a starting value of 1 and increments of 1.
I accidentally overlooked that in my SQL which cost me an hour of my life,
so hopefully this helps someone!!!
Annotate the property like below
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
To use identity columns for all value-generated properties on a new model, simply place the following in your context's OnModelCreating():
builder.ForNpgsqlUseIdentityColumns();
This will create make all keys and other properties which have .ValueGeneratedOnAdd() have Identity by default. You can use ForNpgsqlUseIdentityAlwaysColumns() to have Identity always, and you can also specify identity on a property-by-property basis with UseNpgsqlIdentityColumn() and UseNpgsqlIdentityAlwaysColumn().
postgres efcore value generation
Specifying the column type as serial for PostgreSQL to generate the id.
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Column(Order=1, TypeName="serial")]
public int ID { get; set; }
https://www.postgresql.org/docs/current/static/datatype-numeric.html#DATATYPE-SERIAL

Entity Framework auto generate GUID

I am new to EF so here goes.I have a class which contains the following
public class EmailTemplate
{
public Guid Id { get; set; }
[MaxLength(2000)]
public string Html { get; set; }
}
Here is my mapping class
class EmailMapper : EntityTypeConfiguration<EmailTemplate>
{
public EmailMapper()
{
ToTable("EmailTemplate");
HasKey(c => c.Id);
Property(c => c.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
Property(c => c.Id).IsRequired();
}
}
I am trying to call DbContext.SaveChanges(), but I get the following error :
Exception Details: System.Data.SqlClient.SqlException: Cannot insert the value NULL into column 'Id', table 'AutoSendConnection.dbo.EmailTemplates'; column does not allow nulls. INSERT fails.
What am i doing wrong? Why won't EF auto create a unique GUID?
Just decorate the Id field on your EmailTemplate class as below and SQL Server will automatically generate the value on insert.
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Key]
public Guid Id { get; set; }
You can also remove your Mapper class as it's no longer needed.
If using .Net core then this should work for you ...
Use fluent API
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Node>().Property(x => x.ID).HasDefaultValueSql("NEWID()");
}
or
modelBuilder.Entity<Student>().Property(p => p.StudentID)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
Here is a more comprehensive Cheat Sheet for entity framework
Addressing other answers here
None of these other options seem to work and I've questioned this time and time again with the EF team over on github ...
https://github.com/aspnet/EntityFramework6/issues/762
... for some reason the EF dev team seem to think that this is "working by design" and repeatedly close tickets questioning this "bug".
The EF team explanation
For some reason they seem to think that "generating Guids in SQL is considered not best practice and that to ensure the keys are available immediately we should be generating the keys in the app code".
The issue here of course is that highly populated tables run the risk of you taking further business actions consuming an invalid key.
In my case this could break some extremely complex multi server DTC transactions so I don't believe the advice from MS to be correct, that said EF Core doesn't currently support distributed transactions at all so in a focused context they may have a point.
My answer (which actually works)
In short, I solved this by "manually hacking" the generated migration after generating it ...
EF code first migrations, DB generated guid keys
To quote the other question the answer is as follows:
Generate the migration script as you normally would putting both attributes on the key property like this ...
public class Foo
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
}
... declaratively speaking the entity is now correct.
The migration it will generate will look something like:
CreateTable(
"dbo.Foos",
c => new
{
Id = c.Guid(nullable: false),
...
})
.PrimaryKey(t => t.Id)
...;
... I have not been able to pin down why, but in some situations this will work and in others it won't (run the migration, perform an insert to test).
If it fails, roll the migration back then modify it to read something like ...
CreateTable(
"dbo.Foos",
c => new
{
Id = c.Guid(nullable: false, defaultValueSql: "newid()"),
...
})
.PrimaryKey(t => t.Id)
...;
... the extra code here tells SQL to generate the key as we would expect.
As a rule of thumb I would apply this change all the time for consistency reasons and it means that at a glance your migrations will show you exactly what keys are db generated and of course which ones don't.
After a long investigation, I found out that in EF Core 3.1 you need to use
builder.Property(e => e.Id).ValueGeneratedOnAdd();
Set the default sql value of the field to 'newsequentialid()' in the mapping configuration.
You can also set Default Value of ID as NewID() in Sql Server itself and pass the GUID as null
I used to do it in SSMS.
I prefer to leave the database to generate the id automatically for example the following schema:
CREATE TABLE [dbo].[MyTable](
[MyId] [uniqueidentifier] NOT NULL CONSTRAINT [DF_Booking_BookingId] DEFAULT (newsequentialid())
)
Then in the code first mapping I specify the following to tell Entity Framework that the database will take care of generating the value on insert.
Property(a => a.MyId).IsRequired().HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
I encountered this issue in .NET 6. Some background is that we use int for primary keys but a new requirement ment that parts of the system needed to be in sync with other systems and we could no longer depend on our int keys. We decided to use a hybrid approach with auto-increment primary key integer id column and a GUID column as described here:
https://dba.stackexchange.com/a/96990/80960
Basically the model looked like this:
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Guid { get; set; }
Migration looked like this:
migrationBuilder.AddColumn<Guid>(
name: "Guid",
table: "Products",
type: "uniqueidentifier",
nullable: false,
defaultValue: new Guid("00000000-0000-0000-0000-000000000000"));
ApplicationDbContextModelSnapshot.cs:
b.Property<Guid>("Guid")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
I thought this meant that every old value would get 00000000-0000-0000-0000-000000000000 and new values would receive ValueGeneratedOnAdd. However when I tested to add a new value I still got value 00000000-0000-0000-0000-000000000000. See image below:
I then tried to use defaultValue: Guid.NewGuid()); instead of defaultValue: new Guid("00000000-0000-0000-0000-000000000000")); in migration.
This meant that every old and every new value I added got the same Guid but not 00000000-0000-0000-0000-000000000000.
I then switched over to manually add defaultValueSql: "NEWID()" instead of defaultValue: new Guid("00000000-0000-0000-0000-000000000000") in migration.
Now everything started working as expected both with old values and new values:
Now I wanted this functionality to be default for every new Guid added. I therefore modified ApplicationDbContext.cs method protected override void OnModelCreating(ModelBuilder modelBuilder) like this:
foreach (var property in modelBuilder.Model.GetEntityTypes()
.SelectMany(t => t.GetProperties())
.Where(p => p.ClrType == typeof(Guid)))
{
property.SetDefaultValueSql("NEWID()");
}
Model ended up looking like this since [DatabaseGenerated(DatabaseGeneratedOption.Identity)] did not work in this case:
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public Guid Guid { get; set; }
Entity Framework Core Update:
There is no need to use [DatabaseGenerated(DatabaseGeneratedOption.Identity)].
There is no need to use fluent API
EF Core automatically take care of it and generates Id for primary key
Example:
public class DummyEntity
{
public Guid Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
Seeding
_context.DummyEntities.Add(new DummyEntity
{
FirstName = "Abc",
LastName = "Def",
Postion = "User",
});
_context.SaveChanges();

Entity Framework error: Cannot insert explicit value for identity column in table

I'm getting this error on EF.
Cannot insert explicit value for identity column in table
'GroupMembers_New' when IDENTITY_INSERT is set to OFF.
The column on the Db is identity increment and on the EF design file, StoreGeneratedPattern is identity as well. Seems like EF is trying to insert 0 every time I try to save.
Some suggestions says ID is reserved on tables or drop the table and rerun the scripts.
Any ideas?
Here's some code:
GroupMember groupMember = new GroupMember();
groupMember.GroupId = group.Id;
groupMember.UserId = (new UserId(group.Owner));
//groupMember.Id = _groupContext.GroupMembers.Count();
group.GroupMembers.Add(groupMember);
_groupContext.SaveChanges();
I have run into this before. This error means you are trying to assign a value explicitly to a column where the database automatically assigns it.
Suggestion:
Update your edmx file to reflect any changes you may have made in the database.
If the database automatically assigns the value, you should see the "IsDbGenerated=true" attribute in your designer file under that property. If it's not there, you can add it manually.
Try this:
using System.ComponentModel.DataAnnotations.Schema;
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public decimal Identity_Col { get; set; }
The Entity Framework class file adds these lines of code to the Identity column.
Put these attribs on top of the property which is identity:
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
I encountered the same problem and error message in my AspNetCore 2.x application.
The only way I could solve it was by removing this line in the ModelBuilder.Entity method of the DbContext class:
// remove: entity.Property(e => e.Id).ValueGeneratedNever();
EF Code first: Because of an auto-increment PK 'id' field AND a guid column, design like this:
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid FileToken { get; set; }
there was a duplicate identity. I changed it to:
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
[DefaultValue("newid()")]
public Guid FileToken { get; set; }
and the problem went away.
In EF 6, there is a property of the field/column in your model for doing this:
StoreGeneratedPattern.
Set this to "Identity" in the property dropdown list.
(I don't know about EF 4. The above answer, using IsDbGenerated, seems to be for EF 4.)
And this corresponds in the underlying XML to an attribute to the element:
<Property Name="MyTableId" Type="int" Nullable="false" StoreGeneratedPattern="Identity" />
--but you don't need to deal with the XML manually, since you can use the designer.
How this gets messed up isn't clear. I had the problem even after refreshing my model from the database. Perhaps it gets confused if you set the PK on the table, or change its name, after you have already generated the model. (I am using the table/database-first approach, not code first.)
You can't use the above approach of putting the C# attribute on the entity code, because in this situation the entity code is generated by EF. EF is supposed to understand ("by itself") that the field is an identity.
I had this issue in my app; and got fixed it changing the property "StoredGeneratedPattern" of the id field to Identity.
So, Go to the model; look up for the table; click on propierties of the primary key fiel; and change the property.
See intercepting Entity Insert for generated always columns like StartTime and EndTime columns on history tables, rowversion columns as well.
I solved this by removing primary key in model from inserting data. because primary key auto increment.
var book = new Book
{
// Id = 1, //Don't need to write this
Genre = "Technology",
Author = "Charles Petzold",
Title = "Programming Windows 5th Edition",
Price = 30,
Publisher = "Microsoft Press"
};
_unitOfWork.Books.Add(book);
Well, You need give a value to ID, for example for the object Auto, just you should VarAuto.Id = 0;
After that you could do it something like this =>
using( MyContext db = new MyContext()){
db.Autos.Add(VarAuto);
db.SaveChanges();
}
That is the solution just give value to id, EF could be recognize the identity value in the table.
Just Try.
I'm using DB first and the table has identity column. I didn't use the db-scaffolding to generate this, I copied it from another entity and by mistake I took this property with.
So
Try to check the DBContext Class. I got this error, and the issue was with this property ".ValueGeneratedNever()"
I have just removed it and it works fine,
modelBuilder.Entity<TableName>(entity =>
{
entity.Property(e => e.Id)
//.ValueGeneratedNever()
.HasColumnName("ID");
});
Note: a moderator deleted this answer as a duplicate and left my other answer up, on a question with only the sql-server tag (which was the first question I arrived at from google). Since this question has the entity framework tag, posting the answer again here.
This is for EntityFramework Core 3.1.22. Using the wrong property to specify a foreign key causes Entity Framework to demote the primary key to ... something else. Entity Framework will then always attempt to insert an explicit value, which throws a database exception because it can't insert the value it's been told is a primary key and shouldn't be inserted.
Microsoft.EntityFrameworkCore.DbUpdateException: 'An error occurred while updating the entries. See the inner exception for details.'
Inner Exception:
SqlException: Cannot insert explicit value for identity column in table 'FOO' when IDENTITY_INSERT is set to OFF.
Code example. We have a 1-to-1 class mapping:
public class Foo /* child */
{
public int FooPrimaryKey { get; set; }
public int BarPrimaryKey { get; set; }
public virtual Bar PropertyBar {get; set; }
}
public class Bar
{
public int BarPrimaryKey { get; set; }
public virtual Foo PropertyFoo {get; set; }
}
modelBuilder.Entity<Foo>(entity =>
{
entity.HasKey(e => e.FooPrimaryKey);
entity.ToTable("FOO", "dbo");
entity.HasOne(d => d.PropertyBar)
.WithOne(x => x.PropertyFoo)
// wrong, this throws the above exception
.HasForeignKey<Bar>(x => x.BarPrimaryKey);
});
The foreign key should instead be (same key, different type):
.HasForeignKey<Foo>(x => x.BarPrimaryKey);
If you don't want to use EF core's auto-generating primary key values feature, you can turn it off. You can add your data to the primary key
It should resolve the error - Set Identity Insert off
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int StudentId { get; set; }
Setting Database Generation option to None helped me.
You can find more about it here- https://learn.microsoft.com/en-us/ef/core/modeling/generated-properties?tabs=data-annotations
Add this line in order to allow the Id column to receive 1,2,3 and 4 values instead of being auto-numbered.
Sql("SET IDENTITY_INSERT MembershipTypes ON")

Categories