2

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?

1 Answer 1

2

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)
Sign up to request clarification or add additional context in comments.

6 Comments

This will work, but then when I use the following with the include properties: var user = _userRepository.GetFirstOrDefault(u => u.Id == newUser.Id, "Language,andsomeotherfields"), all other related entities will be filled except Language. So somehow EF Core can't related the LanguageId I have inserted earlier to the UserLanguageEntity record in the database.
Can you paste the code that you are using when retrieving the user?
Sure: public TEntity GetFirstOrDefault(Expression<Func<TEntity, bool>> filter, string includeProperties) { if (!string.IsNullOrEmpty(includeProperties)) { foreach (string includeProperty in includeProperties.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) { Entities.Include(includeProperty); } } return Entities.FirstOrDefault(filter); }
Just as I wanted to test and debug it, my project is acting weird. When starting it, the program automatically stops: The program '[15188] iisexpress.exe' has exited with code -1073741819 (0xc0000005) 'Access violation'. So I am attempting to fix this before I can test your recommended code!
Very weird, but even my solution suddenly works now with my own GetFirstOrDefault method. And also your solution works. Haha I am so confused now. But anyway, thanks for your help! Both solutions work, and suddenly so does mine as well, which didn't work before (...)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.