2012-10-25 112 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的存在,因此它創建了一個空記錄。

希望這可以幫助別人。

問候。