Home > Mobile >  EF Core - "The property is part of a key and so cannot be modified or marked as modified"
EF Core - "The property is part of a key and so cannot be modified or marked as modified"

Time:01-08

I develop an app where I have entities like Language and Dialect. One language has many dialects, so it's classic one to many relation:

public class Language
    {
        [Required]
        [Key]
        public long LanguageId { get; set; }
        public string LanguageName { get; set; } = String.Empty;

        public IEnumerable<Dialect>? Dialects { get; set; }
    }
public class Dialect
    {
        [Required]
        [Key]
        public long DialectId { get; set; }
        public string DialectName { get; set; } = String.Empty;
        [Required]
        public long LanguageId { get; set; }

        public Language? Language { get; set; }
    }
modelBuilder.Entity<Language>()
                .HasMany(l => l.Dialects)
                .WithOne(d => d.Language)
                .HasForeignKey(d => d.DialectId);

I have a method to add a new Dialect into an existing Language:

public async Task<bool> AddDialectAsync(Dialect dialect)
        {
            try
            {
                var maxId = await db.Dialects.MaxAsync(x => x.DialectId);
                dialect.DialectId = maxId   1;
                await db.Dialects.AddAsync(dialect);
                return await db.SaveChangesAsync() >= 1;
            }
            catch (Exception ex)
            {
                return false;
            }
        }

The problem is, when controller invokes AddDialect method, there is always an exception when line return await db.SaveChangesAsync() >= 1; is reached. At this point the dialect object looks like this:

dialect.DialectId = 5,
dialect.DialectName = "american",
dialect.LanguageId = 1

but there is always an exception: "The property 'Dialect.DialectId' is part of a key and so cannot be modified or marked as modified. To change the principal of an existing entity with an identifying foreign key, first delete the dependent and invoke 'SaveChanges', and then associate the dependent with the new principal."

If I drop the lines var maxId = await db.Dialects.MaxAsync(x => x.DialectId); dialect.DialectId = maxId 1; nothing changes.

App uses PostgreSQL database. I doubt that there is a problem with the database, because SQL query

INSERT INTO public."Dialects"(
    "DialectId", "DialectName", "LanguageId")
    VALUES (5, 'american', 1);

works fine, and row is actually added to the database.

App uses Entity Framework Core 7.0.1.

I ran out of ideas, because I believe that in my previous app there was very similiar relation and I did it the same way, and then it worked.

CodePudding user response:

You should not modify the key in this case. Instead of this, just set auto increment and let EF set it for you.

CodePudding user response:

If you want to set the primary key by yourself you can add [DatabaseGenerated(DatabaseGeneratedOption.None)] to the DialectId :

public class Dialect
{
    [Required]
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public long DialectId { get; set; }
    public string DialectName { get; set; } = String.Empty;
    [Required]
    public long LanguageId { get; set; }

    public Language? Language { get; set; }
}

or just do not set any value, either in the AddDialectAsync or out of it.

  • Related