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

c# ef-core-2.0 entity-framework-core

Question

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!

1
0
8/19/2018 11:31:07 PM

Popular Answer

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.

0
8/20/2018 12:54:43 AM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow