Konrados
Konrados

Reputation: 528

While editing entity getting error: The relationship could not be changed because one or more of the foreign-key properties is non-nullable

I'm using AutoMapper to map models in my app. Adding a new entity is working fine but when I'm trying to update existing entity I get this error:

The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.

My controller:

[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 config:

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();
    }
}

Models:

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; }
}

Packages used in solution:

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

-- EDIT --

Here is my DTOs

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; }
}

Upvotes: 0

Views: 177

Answers (1)

vahid tajari
vahid tajari

Reputation: 1313

In Recipe class,Ingredients propery is required.RecipeDto class must has property with Ingredients name and type of IngredientDto.

Upvotes: 0

Related Questions