I was trying to seed data in a migration using the SeedData method, and one of the fields of this model was an Enum that can have several values. The issue is that when I generate the migration, that specific field is never populated in the migration. It always relays on default value even when I'm trying to set it to something different. I also tried editing one of the already seeded objects included in a previous migration and it's also not generating an UpdateData migration. I manually tested adding myself the UpdateData statement but I wanted to know if we're doing something wrong with SeedData and Enum values.
SourceType.cs
public enum SourceType {
Email,
Sms,
Phone
}
Source.cs
public class Source {
[Key]
public int Id {get; set;}
public string Name {get; set;}
public SourceType Type {get;set;}
}
HasData use
...
modelBuilder.Entity<Source>().HasData(
new Source{
Id = 1,
Name = "Email Source",
Type = SourceType.Email
})
...
BunchOfDateNumbers_Migration.cs Up method
migrationBuilder.InsertData(
table: "Source",
columns: new[]{"Id", "Name"},
values: new[] {1, "Email Source"})
Am I doing something wrong? Do we have to specify enum values manually?
EDIT:
We also set this value by default:
modelBuilder.Entity<Source>(
entity =>
{
entity.Property(e => e.SourceType).HasDefaultValueSql("1");
});
EF Core uses the CLR default to determine if the SQL DEFAULT should be used. Since SourceType.Email is the CLR default (0) it doesn't send an INSERT value so the DEFAULT constraint can be used. There are several ways to "fix" this.
First, you could just start your enum at 1:
enum SourceType {
Email = 1,
Sms,
Phone
}
Or second, you could add a better enum value for the default.
enum SourceType {
Unknown, // "None" or "Default" are also good names
Email,
Sms,
Phone
}
Or third, you can make the property nullable so that null becomes the default CLR value instead of 0.
class Source {
// Nullable to allow both using the DEFAULT and inserting SourceType.Email
public SourceType? Type {get;set;}
}
I have a Model class that defines various fields. I can set the field to be 'datetime' and Entity Framework builds the table and uses 'datetime2(7).
I am trying to override that to set the mssql field to 'date'. I really don't want the time portion.
Likewise, I have another field that I want to set to 'time' (of day). I cannot set that either.
(And for optional completeness, I would like a field for time duration, but I will have to burn that bridge when I come to it.)
This question more broadly applies to using Fluid api to generate any other specific fields.
For date type column you would use DateTime type property and HasColumnType Fluent API:
public class MyEntity
{
// ...
public DateTime DateVal { get; set; }
}
modelBuilder.Entity<MyEntity>()
.Property(e => e.DateVal)
.HasColumnType("date");
For time type column you would simply use TimeSpan type property (no Fluent API is needed):
public class MyEntity
{
// ...
public TimeSpan TimeVal { get; set; }
}
The generated SQL command from the migration would be something like this:
CREATE TABLE [MyEntity] (
[Id] int NOT NULL IDENTITY,
[DateVal] date NOT NULL,
[TimeVal] time NOT NULL,
CONSTRAINT [PK_MyEntity] PRIMARY KEY ([Id])
);
Using EntityFramework code-first, I've created a simple Foo table. Here's my entity:
public class Foo
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public virtual string Id { get; set; }
public virtual string Name { get; set; }
}
However whenever I try to insert a new row, I get a Cannot insert the value NULL into column 'Id'. Why is this happening when I've added a DatabaseGenerated attribute? Deleting and recreating my table makes no difference.
Identities for string column types are not supported with SQL Server. (How do you expect such a string to look like?) To get this working you could - for example - add a computed column/user defined function in SQL Server that formats a string from an ordinary int identity column - as shown here.
you forgot the Key attribute. and there is no need to use virtual for primary key.
as mentioned by Slauma you can't use Identity for string datatype.
Try this code:
public class Foo
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public virtual string Name { get; set; }
}
For anybody reading this in 2020, 'Identity' attributes for string column types are supported using Entity Framework. For example, decorating a string type property in your C# class with the [DatabaseGenerated(DatabaseGeneratedOption.Identity)] attribute tag, then letting Entity Framework create the table through a database-first migration, and inserting that record through your program with Entity Framework methods (AddAsync(), SaveAsync()), auto-generates a string that looks like e.g. 'b652daab-9bb9-5143-a1ae-97a89232ea38'.
MS SQL Server will not auto generate this value however (I trialled it with an Insert SQL statement). Instead, the program / Entity Framework seems to generate it.
I know that is an old thread, but for anyone in the future:
DatabaseGenerated(DatabaseGeneratedOption.Identity)
does not generate any values, it simply let EF know that DB suppose to generate the value as described in the MS documentation. Therefore you must either set a default value in the database, in your model or assign an actual value in the controller.
As Treadmeister stated, identity is working fine with string Id with at least Entity Framework Core 3+. My problem was passing an object from Web App with Id: "" which is string.Empty not null so EF Core was not generating new Id
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")
I've added Entity Framework to an existing project with existing tables. These tables contains a couple of uniqueidentifier columns that is NULL. When I load data from these my model-property is also null and not Guid.Empty. I've tried setting the default value using both the constructor and
AlterColumn("tblItems", "ThreadRoot", c => c.Guid(nullable: true, defaultValue: Guid.Empty));
but it still return null.
How can I achieve this?
When I load data from these my model-property is also null and not Guid.Empty
That's because the data already present will contain null, because they were stored before you issued the AlterColumn method. The default value will be written when a new record is inserted, when the appropriate column is not set.
In your model, just add the default value to the property:
public class Item {
public Guid ThreadRoot { get; set; }
public Item() {
ThreadRoot = Guid.Empty; //default value
}
}