I am working on a ASP.NET Core 2.2 project and I am using Entity Framework Core 2.2 as the ORM for accessing an Azure SQL database.
I have the following two entities/tables which are related to eachother (One-To-Many relationship).
[Table("Users")]
public class UserEntity : BaseGuidEntity
{
.../// other properties
[ForeignKey("Language")]
public int LanguageId { get; set; }
public virtual UserLanguageEntity Language { get; set; }
}
[Table("UserLanguages")]
public class UserLanguageEntity
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
..//other properties
public virtual ICollection<UserEntity> Users { get; set; }
}
I have two different languages already inserted in the database. These two are the only available languages, and no new languages are allowed to be inserted. I use the following code to insert a new user with the related language:
var language = _languageRepository.GetById(newUser.Language.Id);
newUser.LanguageId = language.Id;
newUser.Language = language;
_userRepository.Insert(newUser);
So, I basically want to create a new user with the related existing language as well. But what entity framework core attempts, is creating a new language entity with the already existing values, which will ofcourse cause errors in the SQL db.
Error: System.Data.SqlClient.SqlException (0x80131904): Cannot insert explicit value for identity column in table 'UserLanguages' when IDENTITY_INSERT is set to OFF.
How can I related an existing language record to a new user entity?
Have you tried not to set newUser.Language? There should be no reason for you to do that since you have set LanguageId. Your GetById method _languageRepository.GetById(newUser.Language.Id);
has probably disposed of the context and Insert method is registering that Language object that you are setting and trying to insert it.
Here is how I retrieve entities in my generic repo, maybe this can help you:
public IEnumerable<T> FindBy(Expression<Func<T, bool>> whereCondition, params Expression<Func<T, object>>[] includes)
{
IQueryable<T> query = _dbContext.Set<T>().Where(whereCondition);
if (includes.Any())
return Includes(includes, query);
return query;
}
protected IQueryable<T> Includes(Expression<Func<T, object>>[] includes, IQueryable<T> query)
{
return includes.Aggregate(query, (current, includeProperty) => current.Include(includeProperty));
}
And then you can use it like:
FindBy(r => r.Id == id, incl => incl.Languages)
User contributions licensed under CC BY-SA 3.0