test bild upploas
All checks were successful
Branch - test - Build and Push Backend API Docker Image / build-and-push (push) Successful in 25s
All checks were successful
Branch - test - Build and Push Backend API Docker Image / build-and-push (push) Successful in 25s
This commit is contained in:
@@ -74,7 +74,7 @@ namespace Webshop.Application.Services.Admin
|
|||||||
var slugExists = await _context.Products.AnyAsync(p => p.Slug == productDto.Slug && p.Id != productDto.Id);
|
var slugExists = await _context.Products.AnyAsync(p => p.Slug == productDto.Slug && p.Id != productDto.Id);
|
||||||
if (slugExists) { return ServiceResult.Fail(ServiceResultType.Conflict, $"Ein anderes Produkt mit dem Slug '{productDto.Slug}' existiert bereits."); }
|
if (slugExists) { return ServiceResult.Fail(ServiceResultType.Conflict, $"Ein anderes Produkt mit dem Slug '{productDto.Slug}' existiert bereits."); }
|
||||||
|
|
||||||
// --- DIREKTE ZUWEISUNG STATT UpdateFromDto ---
|
// --- Produkteigenschaften direkt zuweisen ---
|
||||||
existingProduct.Name = productDto.Name;
|
existingProduct.Name = productDto.Name;
|
||||||
existingProduct.Description = productDto.Description;
|
existingProduct.Description = productDto.Description;
|
||||||
existingProduct.SKU = productDto.SKU;
|
existingProduct.SKU = productDto.SKU;
|
||||||
@@ -91,7 +91,7 @@ namespace Webshop.Application.Services.Admin
|
|||||||
existingProduct.FeaturedDisplayOrder = productDto.FeaturedDisplayOrder;
|
existingProduct.FeaturedDisplayOrder = productDto.FeaturedDisplayOrder;
|
||||||
existingProduct.LastModifiedDate = DateTimeOffset.UtcNow;
|
existingProduct.LastModifiedDate = DateTimeOffset.UtcNow;
|
||||||
|
|
||||||
// Kategorien direkt bearbeiten
|
// --- Kategorien neu aufbauen ---
|
||||||
existingProduct.Productcategories.Clear();
|
existingProduct.Productcategories.Clear();
|
||||||
if (productDto.CategorieIds != null)
|
if (productDto.CategorieIds != null)
|
||||||
{
|
{
|
||||||
@@ -100,38 +100,66 @@ namespace Webshop.Application.Services.Admin
|
|||||||
existingProduct.Productcategories.Add(new Productcategorie { categorieId = catId });
|
existingProduct.Productcategories.Add(new Productcategorie { categorieId = catId });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// --- ENDE DIREKTE ZUWEISUNG ---
|
|
||||||
|
|
||||||
// Logik f<>r Bilder (unver<65>ndert)
|
// =========================================================================
|
||||||
|
// --- BILD-LOGIK (SAUBER REFAKTORISIERT MIT "COLLECTION-NEUBAU") ---
|
||||||
|
// =========================================================================
|
||||||
|
var newImageList = new List<ProductImage>();
|
||||||
|
|
||||||
|
// 1. Behalte alle existierenden Bilder, die NICHT gel<65>scht werden sollen
|
||||||
if (productDto.ImagesToDelete != null && productDto.ImagesToDelete.Any())
|
if (productDto.ImagesToDelete != null && productDto.ImagesToDelete.Any())
|
||||||
{
|
{
|
||||||
var imagesToRemove = existingProduct.Images.Where(img => productDto.ImagesToDelete.Contains(img.Id)).ToList();
|
newImageList.AddRange(existingProduct.Images.Where(img => !productDto.ImagesToDelete.Contains(img.Id)));
|
||||||
foreach (var image in imagesToRemove) { existingProduct.Images.Remove(image); }
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
newImageList.AddRange(existingProduct.Images);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Verarbeite das neue Hauptbild (falls vorhanden)
|
||||||
if (productDto.MainImageFile != null)
|
if (productDto.MainImageFile != null)
|
||||||
{
|
{
|
||||||
var oldMainImage = existingProduct.Images.FirstOrDefault(i => i.IsMainImage);
|
// Altes Hauptbild aus der neuen Liste entfernen (falls vorhanden)
|
||||||
if (oldMainImage != null) { existingProduct.Images.Remove(oldMainImage); }
|
var oldMainImage = newImageList.FirstOrDefault(i => i.IsMainImage);
|
||||||
foreach (var img in existingProduct.Images) { img.IsMainImage = false; }
|
if (oldMainImage != null)
|
||||||
|
{
|
||||||
|
newImageList.Remove(oldMainImage);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Alle verbleibenden Bilder als "nicht Hauptbild" markieren
|
||||||
|
foreach (var img in newImageList) { img.IsMainImage = false; }
|
||||||
|
|
||||||
|
// Neues Hauptbild hochladen und zur neuen Liste hinzuf<75>gen
|
||||||
await using var stream = productDto.MainImageFile.OpenReadStream();
|
await using var stream = productDto.MainImageFile.OpenReadStream();
|
||||||
var url = await _fileStorageService.SaveFileAsync(stream, productDto.MainImageFile.FileName, productDto.MainImageFile.ContentType);
|
var url = await _fileStorageService.SaveFileAsync(stream, productDto.MainImageFile.FileName, productDto.MainImageFile.ContentType);
|
||||||
existingProduct.Images.Add(new ProductImage { Url = url, IsMainImage = true });
|
newImageList.Add(new ProductImage { Url = url, IsMainImage = true });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 3. Verarbeite zus<75>tzliche neue Bilder (falls vorhanden)
|
||||||
if (productDto.AdditionalImageFiles != null && productDto.AdditionalImageFiles.Any())
|
if (productDto.AdditionalImageFiles != null && productDto.AdditionalImageFiles.Any())
|
||||||
{
|
{
|
||||||
foreach (var file in productDto.AdditionalImageFiles)
|
foreach (var file in productDto.AdditionalImageFiles)
|
||||||
{
|
{
|
||||||
await using var stream = file.OpenReadStream();
|
await using var stream = file.OpenReadStream();
|
||||||
var url = await _fileStorageService.SaveFileAsync(stream, file.FileName, file.ContentType);
|
var url = await _fileStorageService.SaveFileAsync(stream, file.FileName, file.ContentType);
|
||||||
existingProduct.Images.Add(new ProductImage { Url = url, IsMainImage = false });
|
newImageList.Add(new ProductImage { Url = url, IsMainImage = false });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 4. Berechne die DisplayOrder f<>r die finale neue Liste
|
||||||
int currentOrder = 1;
|
int currentOrder = 1;
|
||||||
foreach (var image in existingProduct.Images.OrderBy(img => !img.IsMainImage).ThenBy(img => img.Id))
|
foreach (var image in newImageList.OrderBy(img => !img.IsMainImage).ThenBy(img => img.Id))
|
||||||
{
|
{
|
||||||
image.DisplayOrder = currentOrder++;
|
image.DisplayOrder = currentOrder++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 5. Ersetze die alte Bild-Collection komplett durch die neue.
|
||||||
|
// EF Core vergleicht die alte und die neue Liste und generiert die n<>tigen SQL-Befehle.
|
||||||
|
existingProduct.Images = newImageList;
|
||||||
|
|
||||||
|
// --- ENDE BILD-LOGIK ---
|
||||||
|
|
||||||
|
// 6. <20>nderungen <20>ber das Repository speichern
|
||||||
await _productRepository.UpdateProductAsync(existingProduct);
|
await _productRepository.UpdateProductAsync(existingProduct);
|
||||||
|
|
||||||
return ServiceResult.Ok();
|
return ServiceResult.Ok();
|
||||||
|
|||||||
@@ -51,12 +51,8 @@ namespace Webshop.Infrastructure.Repositories
|
|||||||
// --- KORRIGIERTE UPDATE-METHODE (OHNE PARAMETER) ---
|
// --- KORRIGIERTE UPDATE-METHODE (OHNE PARAMETER) ---
|
||||||
public async Task UpdateProductAsync(Product product)
|
public async Task UpdateProductAsync(Product product)
|
||||||
{
|
{
|
||||||
// Wir sagen dem DbContext explizit, dass der Zustand dieser Entität "Modifiziert" ist.
|
// Sagen Sie EF explizit, was es tun soll. Das ist der robusteste Weg.
|
||||||
// Das zwingt EF Core dazu, ALLE Eigenschaften der Entität in der UPDATE-Anweisung zu berücksichtigen.
|
_context.Products.Update(product);
|
||||||
// Es umgeht alle möglichen Probleme mit dem Change Tracking, die durch verschiedene Kontexte
|
|
||||||
// oder komplexe Beziehungs-Updates entstehen können.
|
|
||||||
_context.Entry(product).State = EntityState.Modified;
|
|
||||||
|
|
||||||
await _context.SaveChangesAsync();
|
await _context.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user