0

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 }));
7
  • Can you show us the part of code where you are inserting and saving? Commented Oct 25, 2012 at 2:00
  • do you check your model values before SaveChanges operation? Commented Oct 25, 2012 at 3:05
  • show us the stack of the exception Commented Oct 25, 2012 at 3:18
  • @Ammar I had all in the question for you to check Commented Oct 25, 2012 at 8:13
  • @EIYusubov what do you mean by "do you check" ? Commented Oct 25, 2012 at 8:13

2 Answers 2

1

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();
Sign up to request clarification or add additional context in comments.

2 Comments

@Patrick That only works if there are no other instances reference by the album at the time of creation.
UAH! So simple and it make all sense now :) Thank you so much for your help, I will put the answer in details and hope your help can help anybody else. Thanks again. Regards.
1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.