При редактировании объекта, получающего ошибку: отношение не может быть изменено, потому что одно или несколько свойств внешнего ключа не обнуляются - PullRequest
0 голосов
/ 02 января 2019

Я использую AutoMapper для отображения моделей в моем приложении.Добавление новой сущности работает нормально, но когда я пытаюсь обновить существующую сущность, я получаю эту ошибку:

Операция не выполнена: отношение не может быть изменено, поскольку один или несколько внешних ключейсвойства не обнуляются.Когда в отношение вносится изменение, для соответствующего свойства внешнего ключа устанавливается нулевое значение.Если внешний ключ не поддерживает нулевые значения, необходимо определить новое отношение, свойству внешнего ключа должно быть назначено другое ненулевое значение или несвязанный объект должен быть удален.

Myконтроллер:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult RecipeForm(RecipeDto dto, HttpPostedFileBase image)
{
    // validation and upload image file
    var orgRecipe = _context.Recipes
                            .Where(r => r.Id == dto.Id)
                            .Include(i => i.Ingredients)
                            .SingleOrDefault();

    if (orgRecipe != null)
    {
        var recipe = Mapper.Map<RecipeDto, Recipe>(dto, orgRecipe);
        // Uncommenting lines below also doesn't help
        //_context.Set<Recipe>().Attach(recipe);
        //_context.Entry<Recipe>(orgRecipe).State = EntityState.Modified;
    }
    else
    {
        var newRec = Mapper.Map<Recipe>(dto);
        _context.Recipes.Add(newRec);
    }

    _context.SaveChanges();

    return RedirectToAction("Index", "Home");    
}

Конфигурация Automapper:

public static class AutomapperConfig
{
    public static void RegisterMappings()
    {
        AutoMapper.Mapper.Initialize(cfg =>
        {
            cfg.AddCollectionMappers();
            cfg.SetGeneratePropertyMaps<GenerateEntityFrameworkPrimaryKeyPropertyMaps<ApplicationDbContext>>();

            cfg.CreateMap<RecipeDto, Recipe>(MemberList.Source)
                .EqualityComparison(((dto, recipe) => dto.Id == recipe.Id));

            cfg.CreateMap<IngredientDto, Ingredient>(MemberList.Source)
                .EqualityComparison(((dto, ingredient) => dto.Id == ingredient.Id));

        });
        Mapper.AssertConfigurationIsValid();
    }
}

Модели:

public class Recipe
{
    public int Id { get; set; }

    [Required]
    [StringLength(255)]
    public string Name { get; set; }

    [Required]
    public string AboutDish { get; set; }

    [Required]
    public string Directions { get; set; }

    [StringLength(255)]
    public string ImageFilename { get; set; }

    [Required]
    public virtual ICollection<Ingredient> Ingredients { get; set; }

    public virtual ICollection<Rating> Ratings { get; set; }
}

public class Ingredient
{
    public int Id { get; set; }

    [StringLength(255)]
    public string Name { get; set; }

    public int RecipeId { get; set; }
}

Пакеты, используемые в решении:

AutoMapper
AutoMapper.Collection
AutoMapper.Collection.EntityFramework
AutoMapper.Extensions.ExpressionMapping

-РЕДАКТИРОВАТЬ -

Вот мои DTO

public class RecipeDto
{
    public int Id { get; set; }

    [Required]
    [StringLength(255)]
    public string Name { get; set; }

    [Required]
    public string AboutDish { get; set; }

    [Required]
    public string Directions { get; set; }

    [StringLength(255)]
    public string ImageFilename { get; set; }

    [Required]
    public virtual List<IngredientDto> Ingredients { get; set; }

    public virtual ICollection<RatingDto> Ratings { get; set; }
}

public class IngredientDto
{
    public int Id { get; set; }

    [StringLength(255)]
    public string Name { get; set; }

    public int RecipeId { get; set; }
}

1 Ответ

0 голосов
/ 02 января 2019

В классе Recipe свойство Ingredients обязательно. Класс RecipeDto должен иметь свойство с именем Ingredients и типом IngredientDto.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...