EF Core not passing in primary key to query

568 Views Asked by At

I am converting my project to .NET Core (and EF Core).

When I call SaveChanges, I can see that my entity is listed as a modified entity (to be inserted). And the primary key is listed as a set value.

But when I look at the SQL that it outputs, the primary key is not listed among the properties that it sets.

Here is an example of my Entity:

[Table("Bag", Schema = "Shipment")]
public partial class Bag
{
    [Key]
    [StringLength(11)]
    public string BagNumber { get; set; }
    [ForeignKey("Box")]
    public long BoxId { get; set; }
    public virtual Box Box { get; set; }
    public bool IsOpened { get; set; }
    // ... More stuff below

Entity Framework Core makes a merge statement out of the insert. As I said above, it does not have my primary key in the query (in this case BagNumber).

I thought that perhaps .NET Core assumed that all keys are autogenerated on the database. To test this I tried setting [DatabaseGenerated(DatabaseGeneratedOption.None)] on the key. But that gave me an error about using a temporary value for my key (not sure what that is about).

I verified that SaveChanges is getting the primary key (BagNumber) by overriding SaveChanges and iterating through the added and modified entities.

Not sure what else to try. (Note: This all worked fine in Entity Framework 6.)

How can I get Entity Framework Core to not strip out my primary key?

2

There are 2 best solutions below

0
On BEST ANSWER

EF core uses Autogenerated (autoincrement) field for primary keys by default. If you want to change this behaviour you can use

[DatabaseGenerated(DatabaseGeneratedOption.None)] or [DatabaseGenerated(DatabaseGeneratedOption.Identity)] or [DatabaseGenerated(DatabaseGeneratedOption.Computed)]

attributes on the key property.

But you must ensure that the database provider you use supports this attribute.

4
On

You didn't have correct definition of keys in your entity. If you want to set identity by sql server, property type must be numeric

public class Bag
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
public int BagNumber { get; set; }

[ForeignKey("BoxId")]
public virtual Box Box { get; set; }
public long BoxId { get; set; }

public bool IsOpened { get; set; }
// ... More stuff below

Another approach set key by your codes before save changes