Reputation: 2781
I'm trying to insert a new Entity in EF:
public class Ad
{
// Primary properties
public int Kms { get; set; }
// Navigation properties
public virtual Model Model { get; set; }
}
And I receive from the View the model like this (example values):
kms = 222 Model.Id = 3
Then when I do the Add and SaveChanges of the Entity Framework, I get a NULL record inserted in the Model Table (that generated a new ID) and a record in the Ad Table with the new inserted Model Id.
Why is this happening?
Service Layer:
public void CreateAd(CreateAdDto adDto)
{
var adDomain = Mapper.Map<CreateAdDto, Ad>(adDto);
_adRepository.Add(adDomain);
_adRepository.Save();
}
Repository:
public void Add(T entity)
{
_dbSet.Add(entity);
}
public void Save()
{
try
{
_dataContext.SaveChanges();
}
catch (DbEntityValidationException e)
{
var s = e.EntityValidationErrors.ToList();
throw;
}
}
ViewModel:
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; }
}
The Mapping:
Mapper.CreateMap<CreateAdDto, Ad>().ForMember(dest => dest.Model, opt => opt.MapFrom(src => new Model { Id = src.Model_Id }));
Upvotes: 0
Views: 1094
Reputation: 2781
SOLUTION BASED ON @Eranga Answer (thanks man!)
Hope this can help somebody else as it help me thanks to @Eranga.
What it was happening is that in the Mapping from DTO to DOMAIN, the Model entity was maping from an Model_Id coming from a Dropdownlist in the View to an Entity Model (as you can see in the mapping line in the question).
Then, when it was added to the database trough Entity Framework, the EF was not aware of the existence of the Model navigation property in the Ad Domain Entity.
So what I had to create to solve this was adding a new method to my repository to handle the possibility to attach the Model Entity to the Ad Entity context:
public void Attach(T entity)
{
_dbSet.Attach(entity);
}
and ad the attach in the Ad Service Create method:
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();
}
So now, when the adDomain object arrives to the EF trough the _adRepository.Add, it already knows about the existence of the navigation property Model, and can add the new adDomain ojbect.
Before, what it was happening is that, when the adDomain object was arriving at the EF, the EF was not aware of the Model existence so it was creating an null record.
Hope this help anybody else.
Regards.
Upvotes: 1
Reputation: 32437
If you just call the Add
method on the Ad
instance, all the related entities are treated as new entities. Therefore you can attach the Model
instance first and add the Ad
.
context.Models.Attach(ad.Model);
context.Ads.Add(ad);
context.SaveChanges();
Upvotes: 1