C
C#2w ago
Juks

Problem while "dotnet ef migrations add Init"

When I'm trying to add data base migration i get error "The seed entity for entity type 'Contract' cannot be added because a non-zero value is required for property 'ContractId'. Consider providing a negative value to avoid collisions with non-seed data." table (look screenshot) insert :
new Contract
{
CustomerId = 1, SoftwareId = 1, Version = "1.0", StartDate = new DateTime(2024, 1, 1),
EndDate = new DateTime(2024, 1, 10), Price = 1000.00m, DiscountId = 1, SupportYears = 1,
IsSigned = false
},
new Contract
{
CustomerId = 1, SoftwareId = 1, Version = "1.0", StartDate = new DateTime(2024, 1, 1),
EndDate = new DateTime(2024, 1, 10), Price = 1000.00m, DiscountId = 1, SupportYears = 1,
IsSigned = false
},
table has autoincrementation:
modelBuilder.Entity<Contract>()
.Property(c => c.ContractId)
.ValueGeneratedOnAdd();
modelBuilder.Entity<Contract>()
.Property(c => c.ContractId)
.ValueGeneratedOnAdd();
table code:
using System.ComponentModel.DataAnnotations.Schema;

namespace Company_APBD.Models;

public class Contract
{
public int ContractId { get; set; }
public int CustomerId { get; set; }
public int SoftwareId { get; set; }
public string Version { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public decimal Price { get; set; }
public int DiscountId { get; set; }
public int SupportYears { get; set; }
public bool IsSigned { get; set; }


}
using System.ComponentModel.DataAnnotations.Schema;

namespace Company_APBD.Models;

public class Contract
{
public int ContractId { get; set; }
public int CustomerId { get; set; }
public int SoftwareId { get; set; }
public string Version { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public decimal Price { get; set; }
public int DiscountId { get; set; }
public int SupportYears { get; set; }
public bool IsSigned { get; set; }


}
No description
No description
32 Replies
Salman
Salman2w ago
You don't need this code :
c#
modelBuilder.Entity<Contract>()
.Property(c => c.ContractId)
.ValueGeneratedOnAdd();
c#
modelBuilder.Entity<Contract>()
.Property(c => c.ContractId)
.ValueGeneratedOnAdd();
EfCore knows that ContractId is the PK of your table so you don't need to specify it manually. Remove it , delete the previous migrations and then add a fresh migration
Juks
Juks2w ago
still same problem my migration doesn't even create so i cant delete anything
Salman
Salman2w ago
can you show the entire db context class and the full error you get while migration ?
Juks
Juks2w ago
sure wait let me add it to github
Salman
Salman2w ago
sure
Juks
Juks2w ago
GitHub
GitHub - Juks0/CompanyAPI at master
Contribute to Juks0/CompanyAPI development by creating an account on GitHub.
Salman
Salman2w ago
this code is also redundant :
c#
modelBuilder.Entity<Customer>().HasKey(c => c.CustomerId);
modelBuilder.Entity<Discount>().HasKey(s => s.DiscountId);
modelBuilder.Entity<Contract>().HasKey(c => c.ContractId);
modelBuilder.Entity<Employee>().HasKey(e => e.EmployeeId);
modelBuilder.Entity<Subscription>().HasKey(s => s.SubscriptionId);
c#
modelBuilder.Entity<Customer>().HasKey(c => c.CustomerId);
modelBuilder.Entity<Discount>().HasKey(s => s.DiscountId);
modelBuilder.Entity<Contract>().HasKey(c => c.ContractId);
modelBuilder.Entity<Employee>().HasKey(e => e.EmployeeId);
modelBuilder.Entity<Subscription>().HasKey(s => s.SubscriptionId);
Juks
Juks2w ago
deleted it, still the same
Salman
Salman2w ago
c#
new Customer
{
CustomerId = 6, CustomerType = "Company", Address = "303 Birch St, Warsaw, Poland",
Email = "info@company1.com", PhoneNumber = "+48678901234"
},
c#
new Customer
{
CustomerId = 6, CustomerType = "Company", Address = "303 Birch St, Warsaw, Poland",
Email = "info@company1.com", PhoneNumber = "+48678901234"
},
why manually passing the CustomerId ?
Juks
Juks2w ago
oh there are 2 customer insterts my bad
Salman
Salman2w ago
clean up your DB Context class...and see if it works. Overall code seems fine to me other than manually specifying the PK etc
Juks
Juks2w ago
i made Insert for companyCustomer, i get diffrent error withnot specyfying pk exactly i need to specify primary ket at the top of class in Models? and every goreign key like here?
using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.EntityFrameworkCore;

namespace APBD_kol2.Models;


[Table("backpacks")]
[PrimaryKey(nameof(CharacterId), nameof(ItemId))]
public class Backpacks
{
public int CharacterId { get; set; }
public int ItemId { get; set; }
public int Amount { get; set; }

[ForeignKey(nameof(CharacterId))]
public Characters Characters { get; set; }
[ForeignKey(nameof(ItemId))]
public Items Items { get; set; }

}
using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.EntityFrameworkCore;

namespace APBD_kol2.Models;


[Table("backpacks")]
[PrimaryKey(nameof(CharacterId), nameof(ItemId))]
public class Backpacks
{
public int CharacterId { get; set; }
public int ItemId { get; set; }
public int Amount { get; set; }

[ForeignKey(nameof(CharacterId))]
public Characters Characters { get; set; }
[ForeignKey(nameof(ItemId))]
public Items Items { get; set; }

}
Salman
Salman2w ago
does the migration work when you manually add the PK while seeding the data ?
Juks
Juks2w ago
wym manually
Salman
Salman2w ago
no you don't need that
Juks
Juks2w ago
so how should i do it then?
Salman
Salman2w ago
I mean when you include the PK in the object while seeding
Juks
Juks2w ago
let me check
Salman
Salman2w ago
sure, include the PK in the objects and then see
Juks
Juks2w ago
yh it did work so if i dont provide anything just leave this blind it will know it need to autoincrement ID? no it wont when i didnt provide pk manually i get the same error The seed entity for entity type 'Customer' cannot be added because a non-zero value is required for property 'CustomerId'. Consider providing a negative value to avoid collisions with non-seed data.
Salman
Salman2w ago
You need to provide the PK while seeding but not in the application while inserting You will see when you Will add a new record using EF Core without providing PK , it'll work
Juks
Juks2w ago
seeding means where?
Salman
Salman2w ago
In Db Context
Juks
Juks2w ago
yeah i know that, but could you provide me an example, i have no idea where to specify a PK
Salman
Salman2w ago
well listen. let's say your model is called Book , it'll look like this :
c#
public class Book {
public int Id {get; set;} //BookId can also be used but Id is more concise
public string name {get; set;}
c#
public class Book {
public int Id {get; set;} //BookId can also be used but Id is more concise
public string name {get; set;}
So the Id here is the PK and EFCore knows it . So while seeding the data you need to provide this PK which is Id in this case but in the application while adding something to the schema/database you don't need to specify this. For example you'd just do :
c#

var newBook = new Book { name = "My Book" };
await _myContext.Books.Add(newBook);
await SaveChangesAsync();
c#

var newBook = new Book { name = "My Book" };
await _myContext.Books.Add(newBook);
await SaveChangesAsync();
https://learn.microsoft.com/en-us/ef/core/modeling/keys
Juks
Juks2w ago
Exactly, so i provided class:
public class Customer
{
public int CustomerId { get; set; }

[Required]
public string CustomerType { get; set; }

[Required]
public string Address { get; set; }

[Required]
[EmailAddress]
public string Email { get; set; }

[Required]
[Phone]
public string PhoneNumber { get; set; }
}
public class Customer
{
public int CustomerId { get; set; }

[Required]
public string CustomerType { get; set; }

[Required]
public string Address { get; set; }

[Required]
[EmailAddress]
public string Email { get; set; }

[Required]
[Phone]
public string PhoneNumber { get; set; }
}
my insert looks like this:
modelBuilder.Entity<Customer>().HasData(new List<Customer>
{
new Customer
{
CustomerType = "Company", Address = "606 Aspen St, Wroclaw, Poland",
Email = "sales@company4.com",
PhoneNumber = "+48901234567"
},
new Customer
{
CustomerType = "Company", Address = "707 Willow St, Gdansk, Poland",
Email = "info@company5.com",
PhoneNumber = "+48101234568"
}
});
modelBuilder.Entity<Customer>().HasData(new List<Customer>
{
new Customer
{
CustomerType = "Company", Address = "606 Aspen St, Wroclaw, Poland",
Email = "sales@company4.com",
PhoneNumber = "+48901234567"
},
new Customer
{
CustomerType = "Company", Address = "707 Willow St, Gdansk, Poland",
Email = "info@company5.com",
PhoneNumber = "+48101234568"
}
});
do i need to provide this part of code? I dont think thats the reason
await _myContext.Books.Add(newBook);
await SaveChangesAsync();
await _myContext.Books.Add(newBook);
await SaveChangesAsync();
In link you send there is a Example where we specify PK in model class
[PrimaryKey(nameof(State), nameof(LicensePlate))]
internal class Car
{
public string State { get; set; }
public string LicensePlate { get; set; }

public string Make { get; set; }
public string Model { get; set; }
}
[PrimaryKey(nameof(State), nameof(LicensePlate))]
internal class Car
{
public string State { get; set; }
public string LicensePlate { get; set; }

public string Make { get; set; }
public string Model { get; set; }
}
should'nt i do it like that? and btw thanks for your help you're legend
Salman
Salman2w ago
Oh no! As I said while seeding you do need to provide the PK i.e
c#
modelBuilder.Entity<Customer>().HasData(new List<Customer>
{
new Customer
{
CustomerId = 1,
CustomerType = "Company", Address = "606 Aspen St, Wroclaw, Poland",
Email = "sales@company4.com",
PhoneNumber = "+48901234567"
},

});
c#
modelBuilder.Entity<Customer>().HasData(new List<Customer>
{
new Customer
{
CustomerId = 1,
CustomerType = "Company", Address = "606 Aspen St, Wroclaw, Poland",
Email = "sales@company4.com",
PhoneNumber = "+48901234567"
},

});
Juks
Juks2w ago
yh, but how to do it when i dont wan't to provide it
Salman
Salman2w ago
c#
await _myContext.Books.Add(newBook);
await SaveChangesAsync();
c#
await _myContext.Books.Add(newBook);
await SaveChangesAsync();
this part is for the EfCore queries not for the seeding data and is not relevant in the db context class. You'll use EfCore throughout your application . You'd need to provide it while seeding
Juks
Juks2w ago
so to make it clear as i understand it
modelBuilder.Entity<Customer>().HasData(new List<Customer>
{
new Customer
{
CustomerId = 1,
CustomerType = "Company", Address = "606 Aspen St, Wroclaw, Poland",
Email = "sales@company4.com",
PhoneNumber = "+48901234567"
},

});
modelBuilder.Entity<Customer>().HasData(new List<Customer>
{
new Customer
{
CustomerId = 1,
CustomerType = "Company", Address = "606 Aspen St, Wroclaw, Poland",
Email = "sales@company4.com",
PhoneNumber = "+48901234567"
},

});
this is only way to do it because i always need to provide customer ID while seeding, you can't use auto incrementation here?
Salman
Salman2w ago
yes while seeding you'd need to provide it
Juks
Juks2w ago
thanks, ill try to make it now got it thanks a lot my man