Reputation: 528
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
Reputation: 1313
In Recipe class,Ingredients propery is required.RecipeDto class must has property with Ingredients name and type of IngredientDto.
Upvotes: 0