Error when updating products: Database operation expected to affect 1 row(s) but actually affected 0 row(s) while renaming images


I’ve written a tool that basically renames images. As far as I know, to do this I need to create a copy of the original file and then add that new file SystemId to the BaseProduct or Variant that uses the image.

            var imageFile = FileService.Get(image).MakeWritableClone();
            BlobContainer blobContainer = BlobService.Get(imageFile.BlobUri);

            var filename = $"{productName}_{productImages.IndexOf(image)}.jpg";

            using (SecurityContextService.ActAsSystem())
                var file = new LitiumFile(SystemConfiguration.Instance.ImportImageFieldTemplateId, imageFile.FolderSystemId,
                    blobContainer.Uri, filename.ToCleanFileName())
                    FileSize = imageFile.FileSize,
                    AccessControlList = new HashSet<AccessControlEntry>()
                        new AccessControlEntry(new Operation(Operations.Entity.Read),
                NewIndexes.Add(imageFile.SystemId, file.SystemId);

                return file.SystemId;

When I run the tool I sooner or later encounter the following error:
Database operation expected to affect 1 row(s) but actually affected 0 row(s). Data may have been modified or deleted since entities were loaded. See for information on understanding and handling optimistic concurrency exceptions.

When trying to run .Update on either my BaseProduct- or VariantService, it seems to me like it’s completely random when it happens.
I looked through the slack channel and found a thread about this re: version 5.5.1 where it was advised to run a SQL-query to clean up indexes. So I tried that once with some success but after about 1000 baseproducts later I encountered the same problem, so I went as far as to run the script after every base product change
(I get a baseproduct and fix all variants and the bp itself in each iteration of this loop)

SO basically I’m asking for anything that can assist me with this? is there an easier way to rename 22000 images or should I consider doing it some other way?

thanks in advance

Litium version: 6.2.0

Why not only update the filename on the existing image?

var imageFile = FileService.Get(image).MakeWritableClone();
imageFile.Name =  $"{productName}_{productImages.IndexOf(image)}.jpg";

When you call the FileService.Delete(imageFile); also the blob that is connected to that image will be physical removed. If you should create an copy of the file you also need to make a copy of the blob itself so the copy will get a new blob uri.

Wow, I’ve completely missed that I get access to the Name property on my Writable clone.
That’s what I was hoping to do but missed completely. I’ll try it out. Thanks

Follow up:
does the rename also rename the actual file?
One of the reasons I needed to rename files was because the source we fetched the images from originally apparently had som issues giving us correct file names to begin with, resulting in some images getting imported like imagename.jpeg.02 or other similar.
The rename operation worked like a charm now, but the images aren’t loaded like jpegs.

The physical file that is stored on disc will have a GUID as the name, the url that is created will have the file.Name as the name of the file that the user will download.

okay, I see, but am I able to change the file type on the physical file or is it saved with only the guid as filename?
Seeing as how some files will probably have been saved as a unknown file type the first time around, will they be corrected just by changing the filename?

The file extension is part of the file.Name property and have nothing to do with the physical filename. So if you set that to example File.jpg the file will be downloaded as File.jpg.

Alright, thanks for explaining.