c# – EF和Automapper.更新嵌套集合
我试图更新国家实体的嵌套集合(城市).
只是简单的enitities和dto: // EF Models public class Country { public int Id { get; set; } public string Name { get; set; } public virtual ICollection<City> Cities { get; set; } } public class City { public int Id { get; set; } public string Name { get; set; } public int CountryId { get; set; } public int? Population { get; set; } public virtual Country Country { get; set; } } // DTo's public class CountryData : IDTO { public int Id { get; set; } public string Name { get; set; } public virtual ICollection<CityData> Cities { get; set; } } public class CityData : IDTO { public int Id { get; set; } public string Name { get; set; } public int CountryId { get; set; } public int? Population { get; set; } } 代码本身(为了简单起见,在控制台应用程序中测试): using (var context = new Context()) { // getting entity from db,reflect it to dto var countryDTO = context.Countries.FirstOrDefault(x => x.Id == 1).ToDTO<CountryData>(); // add new city to dto countryDTO.Cities.Add(new CityData { CountryId = countryDTO.Id,Name = "new city",Population = 100000 }); // change existing city name countryDTO.Cities.FirstOrDefault(x => x.Id == 4).Name = "another name"; // retrieving original entity from db var country = context.Countries.FirstOrDefault(x => x.Id == 1); // mapping AutoMapper.Mapper.Map(countryDTO,country); // save and expecting ef to recognize changes context.SaveChanges(); } 此代码抛出异常:
即使最后一次映射后的实体看起来很好,也能正确反映所有变化. 我花了很多时间寻找解决方案却没有结果.请帮忙. 解决方法
问题是您从数据库检索的国家已经有一些城市.当您使用AutoMapper时,如下所示:
// mapping AutoMapper.Mapper.Map(countryDTO,country); AutoMapper正在做类似于创建IColletion< City>的事情.正确(在您的示例中有一个城市),并将此全新集合分配给您的country.Cities属性. 问题是EntityFramework不知道如何处理旧的城市集合. >它应该删除您的旧城市并仅假设新的集合吗? 事实上,EF无法为您做出决定.如果您想继续使用AutoMapper,可以像这样自定义映射: // AutoMapper Profile public class MyProfile : Profile { protected override void Configure() { Mapper.CreateMap<CountryData,Country>() .ForMember(d => d.Cities,opt => opt.Ignore()) .AfterMap((d,e) => AddOrUpdateCities(d,e) ); } private void AddOrUpdateCities(CountryData dto,Country country) { foreach (var cityDTO in dto.Cities) { if (cityDTO.Id == 0) { country.Cities.Add(Mapper.Map<City>(cityDTO)); } else { Mapper.Map(cityDTO,country.Cities.SingleOrDefault(c => c.Id == cityDTO.Id)); } } } } 用于Cities的Ignore()配置使AutoMapper只保留EntityFramework构建的原始代理引用. 然后我们只使用AfterMap()来调用一个完全按照你所要求的行为: >对于新城市,我们从DTO映射到实体(AutoMapper创建一个新的 然后你可以保留原始代码: using (var context = new Context()) { // getting entity from db,reflect it to dto var countryDTO = context.Countries.FirstOrDefault(x => x.Id == 1).ToDTO<CountryData>(); // add new city to dto countryDTO.Cities.Add(new CityData { CountryId = countryDTO.Id,Population = 100000 }); // change existing city name countryDTO.Cities.FirstOrDefault(x => x.Id == 4).Name = "another name"; // retrieving original entity from db var country = context.Countries.FirstOrDefault(x => x.Id == 1); // mapping AutoMapper.Mapper.Map(countryDTO,country); // save and expecting ef to recognize changes context.SaveChanges(); } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- 如何在OC中使用Swift如何在Swift中使用OC
- (MVC3)Ajax.BeginForm中的OnSuccess不执行的问题研究
- fastjson:javabean按字段(field)序列化存储为Map并反序列化
- JSONP跨域请求+简答实现百度搜索
- 远程连接Oracle 服务器 解决Oracle查询中文乱码
- react native封装原生view, 讲解其中的方案设计和通信机制,
- Flex4系列教程之四 – Flash Builder4
- postgresql – 与没有函数包装器的查询相比,SQL函数非常慢
- vb.net 教程 12-2 HtmlDocument类 2
- 在npm项目中安装ruby gems