简体   繁体   中英

EF Core 2.0 Updating one-to-zero-or-one child entity causes error

I have two entities,

[Table("tblProgramTemplate", Schema = "ProgramTemplate")]
public class ProgramTemplate
{
    #region Properties
    [Key]
    public int pkProgramTemplate { get; set; }
    public string fkUser { get; set; }
    public int? fkUploadedMedia { get; set; }
    public DateTime? DateCreated { get; set; }
    public DateTime? DatePublished { get; set; }
    public bool Deleted { get; set; }
    public DateTime? DateDeleted { get; set; }
    public int Likes { get; set; }
    public int Shares { get; set; }
    public int Downloads { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    [Column(TypeName = "decimal(18,2)")]
    public decimal Price { get; set; }
    public int Position { get; set; }
    #endregion

    #region Navigation     
    [ForeignKey("fkUser")]
    public virtual ApplicationUser User { get; set; }
    [ForeignKey("fkUploadedMedia")]
    public virtual UploadedMedia UploadedMedia { get; set; }
    public virtual IEnumerable<Instance.Program> Programs { get; set; }
    public virtual IEnumerable<ProgramParameterTemplate> ProgramParameterTemplates { get; set; }
    public virtual IEnumerable<ApplicationUser> Subscribers { get; set; }
    #endregion

...and...

[Table("tblUploadedMedia", Schema = "Common")]
public class UploadedMedia
{
    #region Properties
    [Key]
    public int pkUploadedMedia { get; set; }
    public string fkUser { get; set; }
    public string FilePath { get; set; } 
    public string OriginalFileName { get; set; }
    public DateTime? DateCreated { get; set; }
    public bool Deleted { get; set; }
    public DateTime? DateDeleted { get; set; }
    #endregion

    #region Navigation
    [ForeignKey("fkUser")]
    public virtual ApplicationUser User { get; set; }
    #endregion
}

When I try to update the reference to UploadedMedia on an existing ProgramTemplate record, it throws the following error

System.InvalidOperationException: 'The property 'pkUploadedMedia' on entity type 'UploadedMedia' 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' then associate the dependent with the new principal.'

The controller code looks like this -

[HttpPost("")]
    public void Upsert([FromBody]ProgramTemplateViewModel vm)
    {
        var userID = _userManager.GetUserAsync(HttpContext.User)?.Result?.Id;
        UploadedMedia programTemplateMedia = null;
        //convert the base64 string to byte array
        if (!string.IsNullOrEmpty(vm.UploadedMedia.FileData) && vm.UploadedMedia.pkUploadedMedia == null)
        {
            var imageBytes = Convert.FromBase64String(vm.UploadedMedia.FileData);
            var filePath = string.Format("{0}/{1}{2}", "./ClientApp/src/assets", Guid.NewGuid(), vm.UploadedMedia.OriginalFileName);
            using (FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate))
            {
                fs.Write(imageBytes);
                fs.Flush();
            }

            programTemplateMedia = new UploadedMedia()
            {
                FilePath = filePath,
                OriginalFileName = vm.UploadedMedia.OriginalFileName,
                DateCreated = DateTime.Now,
                fkUser = userID
            };
        } 

        //if ID is null, insert, else update
        if (vm.pkProgramTemplate == null)
        {
            var template = vm.Adapt<ProgramTemplate>();
            template.fkUser = userID;
            if(programTemplateMedia != null)
            {
                template.UploadedMedia = programTemplateMedia;
            }
            _templateService.AddEntity(template);
        }
        else
        {
            var template = _templateService.GetEntityById(vm.pkProgramTemplate.Value);
            template = vm.Adapt(template);                

            if (programTemplateMedia != null)
            {                    
                template.UploadedMedia = programTemplateMedia;
            }
            _templateService.UpdateEntity(template);
        }
    }

It works fine when inserting, but fails to update when the assigning a new uploadedMedia object. Does anyone know why this would occur? I dont want to delete either object from the db. Is it an issue with my configuration? Thank you kindly for your time!

This is an issue with mapster mapping the entity erroneously. I modified my config to ignore that property when the source is a view model to an entity, and it works fine.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM