Reputation: 779
I ran into a very weird problem I've never seen before. I'm using .net CORE 3.0 + EF. I have two database models, which are
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public Dog Dog { get; set; }
}
and
public class Dog
{
public int Id { get; set; }
public string Name { get; set; }
}
So, let's say I already have a Dog record in my database with id=1 and Name = "Bimbo". Now, I want to add a person with an existing dog:
var p = new Person
{
Name = "Peter",
Dog = new Dog
{
Id = 1
};
};
_dbContext.Persons.Add(p);
Then I get
Cannot insert explicit value for identity column in table 'Dogs' when IDENTITY_INSERT is set to OFF
I understand that EF tries to insert a dog as a new record, while I need it to bind my new Person record with an existing Dog record.
I found this solution which suggests setting a foreign key explicitly. Is there another way to do it? Or is it the right way to handle such situation? EF Core insert explicit value for identity column
Upvotes: 5
Views: 3700
Reputation: 19106
You have three options to do that
Use the Foreign-Key property
using ( var db = new MyDbContext(options) )
{
var person = new Person
{
Name = "Paul",
DogId = 1
};
db.Persons.Add(person);
await db.SaveChangesAsync();
}
Load the dog instance from the context and use that instance
using ( var db = new MyDbContext(options) )
{
var dog = db.Dogs.Find(1);
var person = new Person
{
Name = "Paul",
Dog = dog
};
db.Persons.Add(person);
await db.SaveChangesAsync();
}
Create a dog instance with explicit ID and attach that to the context
using ( var db = new MyDbContext(options) )
{
var dog = new Dog
{
Id = 1
};
db.Attach(dog);
var person = new Person
{
Name = "Paul",
Dog = dog
};
db.Persons.Add(person);
await db.SaveChangesAsync();
}
See working example on .net fiddle
Upvotes: 8
Reputation: 255
When you add the Person object to the context, EF sets its state to Added, as well as any object it references that has their primary key set (as stated here). This is why EF tries to insert a new Dog object into the database with a new id, while the exception states that the ids for the Dogs table are generated by the database.
To work around this you can manually set the state of the new Dog object to Unchanged which will prevent EF from inserting a new record to the database.:
_dbContext.Entry(person.Dog).State = EntityState.Unchanged
Better solutions will be to add a DogId property to the Person object and set it instead of creating a new Dog instance or to load the Dog object from the database and set it to the Dog property of the Person object (as suggested in the comments).
Upvotes: 1
Reputation: 249
you can explicitly add the Foreign key to person
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public int DogId {get;set;}
public Dog Dog { get; set; }
}
then you can the add the dog as reference without load it to context
var p = new Person
{
Name = "Peter",
DogId = 1
};
_dbContext.Persons.Add(p)
;
Upvotes: 1