C# Entity Framework 6 - AutoMapper 6 - Collections/List - 添加和更新有效但删除项目会引发错误
C# Entity Framework 6 - AutoMapper 6 - Collections/List - Add and Update works but removing item throws an 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.
我知道在这种情况下 Description
只会得到一个空外键,但永远不会被删除。我见过一些例子,他们建议循环遍历每个 child 项目并一个一个地删除它们。 Imao 我认为应该有更好的方法。我正在寻找的是一个影响最小的解决方案,只需告诉 EF 删除整个项目,而不仅仅是将外键设为 null。
使用 AutoMapper,AutoMapper.Collection 和 AutoMapper.Collection。EntityFramework。
控制器方法:
public async Task<IHttpActionResult> UpdateArticle(ArticleViewModel articleVm)
{
Article articleOriginal = await iArticleRepository.GetAsync(articleVm.Id);
Article updatedArticle = Mapper.Map<ArticleViewModel, Article>(articleVm, articleOriginal);
await iArticleRepository.UpdateAsync(updatedArticle);
return Ok();
}
映射:
Mapper.Initialize(cfg =>
{
cfg.AddCollectionMappers();
cfg.SetGeneratePropertyMaps<GenerateEntityFrameworkPrimaryKeyPropertyMaps<DbContext>>();
cfg.CreateMap<ArticleViewModel, Article>(MemberList.Source)
.EqualityComparison((src, dst) => src.Id == dst.Id);
cfg.CreateMap<DescriptionViewModel, Description>(MemberList.Source)
.EqualityComparison((src, dst) => src.Id == dst.Id);
}
Mapper.AssertConfigurationIsValid();
视图模型:
public class ArticleViewModel
{
public int Id { get; set; }
public string Name { get; set; }
public List<DescriptionViewModel> Descriptions { get; set; }
}
public class DescriptionViewModel
{
public int Id { get; set; }
public string Heading { get; set; }
}
型号:
public class Article : IEntity<int>
{
public Article()
{
Descriptions = new List<Description>();
}
[Key]
public int Id { get; set; }
public DateTime Created { get; set; }
public DateTime Updated { get; set; }
[MaxLength(256)]
public string Name { get; set; }
public virtual ICollection<Description> Descriptions { get; set; }
}
public class Description: IEntity<int>
{
[Key]
public int Id { get; set; }
public DateTime Created { get; set; }
public DateTime Updated { get; set; }
[MaxLength(256)]
public string Heading { get; set; }
public int ArticleId { get; set; }
public virtual Article Article { get; set; }
}
从这个答案中得到了解决方案
和这个博客:
http://www.kianryan.co.uk/2013/03/orphaned-child/
代码:
public class Description: IEntity<int>
{
[Key, Column(Order = 0), DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public DateTime Created { get; set; }
public DateTime Updated { get; set; }
[MaxLength(256)]
public string Heading { get; set; }
[Key, Column(Order = 1)]
public int ArticleId { get; set; }
public virtual Article Article { get; set; }
}
我真的可以推荐阅读 Mosh's answer 了解 composition 和 aggregation 之间的区别,因为它将帮助您更好地理解 EF .
正如标题所说,我可以添加和更新,但是在删除时出现错误。
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.
我知道在这种情况下 Description
只会得到一个空外键,但永远不会被删除。我见过一些例子,他们建议循环遍历每个 child 项目并一个一个地删除它们。 Imao 我认为应该有更好的方法。我正在寻找的是一个影响最小的解决方案,只需告诉 EF 删除整个项目,而不仅仅是将外键设为 null。
使用 AutoMapper,AutoMapper.Collection 和 AutoMapper.Collection。EntityFramework。
控制器方法:
public async Task<IHttpActionResult> UpdateArticle(ArticleViewModel articleVm)
{
Article articleOriginal = await iArticleRepository.GetAsync(articleVm.Id);
Article updatedArticle = Mapper.Map<ArticleViewModel, Article>(articleVm, articleOriginal);
await iArticleRepository.UpdateAsync(updatedArticle);
return Ok();
}
映射:
Mapper.Initialize(cfg =>
{
cfg.AddCollectionMappers();
cfg.SetGeneratePropertyMaps<GenerateEntityFrameworkPrimaryKeyPropertyMaps<DbContext>>();
cfg.CreateMap<ArticleViewModel, Article>(MemberList.Source)
.EqualityComparison((src, dst) => src.Id == dst.Id);
cfg.CreateMap<DescriptionViewModel, Description>(MemberList.Source)
.EqualityComparison((src, dst) => src.Id == dst.Id);
}
Mapper.AssertConfigurationIsValid();
视图模型:
public class ArticleViewModel
{
public int Id { get; set; }
public string Name { get; set; }
public List<DescriptionViewModel> Descriptions { get; set; }
}
public class DescriptionViewModel
{
public int Id { get; set; }
public string Heading { get; set; }
}
型号:
public class Article : IEntity<int>
{
public Article()
{
Descriptions = new List<Description>();
}
[Key]
public int Id { get; set; }
public DateTime Created { get; set; }
public DateTime Updated { get; set; }
[MaxLength(256)]
public string Name { get; set; }
public virtual ICollection<Description> Descriptions { get; set; }
}
public class Description: IEntity<int>
{
[Key]
public int Id { get; set; }
public DateTime Created { get; set; }
public DateTime Updated { get; set; }
[MaxLength(256)]
public string Heading { get; set; }
public int ArticleId { get; set; }
public virtual Article Article { get; set; }
}
从这个答案中得到了解决方案
和这个博客:
http://www.kianryan.co.uk/2013/03/orphaned-child/
代码:
public class Description: IEntity<int>
{
[Key, Column(Order = 0), DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public DateTime Created { get; set; }
public DateTime Updated { get; set; }
[MaxLength(256)]
public string Heading { get; set; }
[Key, Column(Order = 1)]
public int ArticleId { get; set; }
public virtual Article Article { get; set; }
}
我真的可以推荐阅读 Mosh's answer 了解 composition 和 aggregation 之间的区别,因为它将帮助您更好地理解 EF .