2012-10-25 106 views
0

我想在EF插入一个新的实体:添加实体实体框架中插入空记录

public class Ad 
{ 
    // Primary properties 
    public int Kms { get; set; } 

    // Navigation properties 
    public virtual Model Model { get; set; } 
} 

我从视图接收模式是这样的(例如值):

公里= 222 Model.Id = 3

然后,当我执行实体框架的Add和SaveChanges时,我得到一个插入模型表(生成一个新的ID)和一个记录在广告表中的NULL记录新插入的模型ID。

这是怎么发生的?

服务层:

public void CreateAd(CreateAdDto adDto) 
    { 
     var adDomain = Mapper.Map<CreateAdDto, Ad>(adDto); 

     _adRepository.Add(adDomain); 
     _adRepository.Save(); 
    } 

存储库:

public void Add(T entity) 
    { 
     _dbSet.Add(entity); 
    } 

    public void Save() 
    { 
     try 
     { 
      _dataContext.SaveChanges(); 
     } 
     catch (DbEntityValidationException e) 
     { 
      var s = e.EntityValidationErrors.ToList(); 
      throw; 
     } 
    } 

视图模型:

public class CreateAdViewModel 
{ 
    // Primary properties 
    public string Version { get; set; } 
    public int Kms { get; set; } 
    public int Year { get; set; } 
    public decimal Price { get; set; } 

    public int Make_Id { get; set; } 
    public int Model_Id { get; set; } 

    // Navigation properties 
    public IEnumerable<SelectListItem> MakeList { get; set; } 
    public IEnumerable<SelectListItem> ModelList { get; set; } 
} 

DTO:

public class CreateAdDto 
{ 
    // Primary properties 
    public int Kms { get; set; } 
    public int Model_Id { get; set; } 
} 

的映射:

 Mapper.CreateMap<CreateAdDto, Ad>().ForMember(dest => dest.Model, opt => opt.MapFrom(src => new Model { Id = src.Model_Id })); 
+0

你能告诉我们你插入和保存的部分代码吗? – Ammar

+0

您是否在SaveChanges操作之前检查您的模型值? –

+0

向我们展示了例外的堆栈 – Jorge

回答

1

如果你只是呼吁Ad实例Add方法,所有相关实体被视为新的实体。因此,您可以先附加Model实例并添加Ad

context.Models.Attach(ad.Model); 
context.Ads.Add(ad); 
context.SaveChanges(); 
+0

@Patrick只有在创建时没有其他实例参考“专辑”时才有效。 – Eranga

+0

UAH!这么简单,现在很合理:)非常感谢你的帮助,我会详细回答你的问题,希望你的帮助能够帮助其他人。再次感谢。问候。 – Patrick

1

解决方案基于@Eranga答(感谢的人!)

希望这可以帮助别人,因为它帮助我感谢@Eranga。

它发生的事情是,在从DTO到DOMAIN的映射中,Model实体是从一个来自View中Dropdownlist的Model_Id映射到一个实体模型(如您可以在问题的映射行中看到的那样) 。

然后,当它通过实体框架添加到数据库时,EF并不知道Ad Domain Entity中存在Model导航属性。

所以我必须创建来解决这个被添加新的方法,以我的仓库处理的可能性的模型实体附加到广告实体方面:

public void Attach(T entity) 
{ 
    _dbSet.Attach(entity); 
} 

和广告在广告附加服务创建方法:

private readonly IRepository<Ad> _adRepository; 
    private readonly IRepository<Search> _searchRepository; 
    private readonly IRepository<Model> _modelRepository; 


    public AdService(IRepository<Ad> adRepository, IRepository<Search> searchRepository, IRepository<Model> modelRepository) 
    { 
     _adRepository = adRepository; 
     _searchRepository = searchRepository; 
     _modelRepository = modelRepository; 
    } 

    public void CreateAd(CreateAdDto adDto) 
    { 
     var adDomain = Mapper.Map<CreateAdDto, Ad>(adDto); 

     _modelRepository.Attach(adDomain.Model); 

     _adRepository.Add(adDomain); 
     _adRepository.Save(); 
    } 

所以现在,当adDomain对象到达的EF线槽_adRepository.Add时候,就已经知道的导航属性模式的存在,并且可以添加新的adDomain ojbect。

之前,发生的事情是,当adDomain对象到达EF时,EF并不知道Model的存在,因此它创建了一个空记录。

希望这可以帮助别人。

问候。