Asked by:
Entity Framework update the parents and add the child objects. Getting error

Question
-
User-1637592233 posted
During the
Edit
I have to update some of the tables with the value from the form, and also have to add some new records on the table.I am always getting the same error:
The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.
My view model is as below:
public class CorporateCustomerUpdateViewModel { public Guid Id { get; set; } public string FullName { get; set; } public CorporateCustomerViewModel CorporateCustomer { get; set; } } public class CorporateCustomerViewModel { public int BusinessTypeId { get; set; } public List<CorporateMemberViewModel> CorporateMembers { get; set; } } public class CorporateMemberViewModel { public string IdNumber { get; set; } public string Name { get; set; } public string Document { get; set; } }
Entities::
public class User { public Guid Id { get; set; } public string FullName { get; set; } public virtual CorporateCustomer CorporateCustomer { get; set; } } public class CorporateCustomer { public int BusinessTypeId { get; set; } public virtual ICollection<CorporateMember> CorporateMembers { get; set;} } public class CorporateMember { public string IdNumber { get; set; } public string Name { get; set; } public string Document { get; set; } }
I am using AutoMapper to map the fields from view models to entities.
Configuration looks like:
public class CorporateCustomerMapper : Profile { CreateMap<CorporateCustomerUpdateViewModel, User>(); }
I am trying to Update the
User
table as below:public void UpdateCorporateCustomerDetail(CorporateCustomerUpdateViewModel model) { var userRepo = _genericUnitOfWork.GetRepository<User, Guid>(); var user = userRepo.GetById(model.Id); var entity = _mapper.Map(model, user); //mapping CorporateCustomerUpdateViewModel to User userRepo.Update(entity); _genericUnitOfWork.SaveChanges(); }
GetById
public TEntity GetById(TKey id) { return _dbSet.Find(id); }
After the MAP the
user.CorporateCustomer.CorporateMembers
is getting null because there is no value onmodel.CorporateCustomer.CorporateMembers
.But that should not be getting null because there are already some
CorporateMembers
in the database which I get duringGetById
.I think here is the problem because EF is going to update the null entry.
Here in the link provided is the discussion about the same scenarios.
I have gone through both the links. But there are the discussion with one
ChildObjects
and no AutoMapper. I cannot figure out where did I actually did something wrong, and where I should change my code.Please can you suggest some code changes, or some hints?
Sunday, March 4, 2018 3:36 AM
All replies
-
User1120430333 posted
Myself, I avoid the UoW and the generic repository patterns like the plague.
I would rather use the non-generic repository with Data Access Layer using the DAO pattern.
Or just Data Access Layer using the Data Access Object pattern.
Sunday, March 4, 2018 5:24 AM -
User-1637592233 posted
Thanks for sharing the link and suggesting a solution but
Is that approach going to help me for the current problems?Sunday, March 4, 2018 5:27 AM -
User1120430333 posted
Is that approach going to help me for the current problems?The approach I was thought many years ago is to keep it simple. There is nothing wrong with the repository pattern being used in a non-generic manner or not use the pattern at all nor the UoW pattern.
http://blog.sapiensworks.com/post/2012/11/01/Repository-vs-DAO.aspx
But you see, you should have had the database CRUD all figured out and tested before you even tried to hook up the UI/presentation layer to the backend, which would make things a whole lot more easier too, knowing that the database code is solid.
You are aware of the information in the link, since Web applications are stateless, right?
http://www.c-sharpcorner.com/UploadFile/d87001/connected-and-disconnected-scenario-in-entity-framework/
Sunday, March 4, 2018 7:45 AM -
User-1637592233 posted
Thanks for your comment ...This shows i am going to be screwed up. or I had to hack my own code to make suitable with the current UI.
Sunday, March 4, 2018 7:53 AM -
User1120430333 posted
It's good that you are trying to use a Repository, but maybe, you should just consider using a Data Access Layer and maybe, the DAO pattern. I'll show you the concept.
But you should also keep in mind what is in the links and the MVC pattern.
http://www.c-sharpcorner.com/UploadFile/56fb14/understanding-separation-of-concern-and-Asp-Net-mvc/
https://docs.microsoft.com/en-us/aspnet/mvc/overview/older-versions-1/overview/understanding-models-views-and-controllers-cs
<copied>
A view should contain only logic related to generating the user interface. A controller should only contain the bare minimum of logic required to return the right view or redirect the user to another action (flow control). Everything else should be contained in the model.+
In general, you should strive for fat models and skinny controllers. Your controller methods should contain only a few lines of code. If a controller action gets too fat, then you should consider moving the logic out to a new class in the Models folder.
<end>
You can view the below thread to see what I am talking about of view -- controller -- model -- DAL using DAO.
http://www.entityframeworktutorial.net/EntityFramework5/attach-disconnected-entity-graph.aspx
https://www.tutorialspoint.com/design_pattern/data_access_object_pattern.htm
https://www.codeproject.com/Articles/1050468/Data-Transfer-Object-Design-Pattern-in-Csharp
The DTO(s) are in the Entities classlib project, and the MVC and the DAL have project reference to Entities and know about the DTO(s).
.
Sunday, March 4, 2018 9:18 AM -
User1400794712 posted
Hi aakashbashyal,
You use breakpoint to debug your project and check the model value.
Set a breakpoint on UpdateCorporateCustomerDetail and check the model's value.
When it comes into the breakpoint, use F10 to execute the code line by line and check the result.
Best Regards,
Daisy
Monday, March 5, 2018 10:03 AM