Add without object graph RRS feed

  • Question

  • I have an Entity called DocumentRequest, which has 3 relationships with User:

            public virtual User Elaborator { get; set; }
            public virtual User Evaluator { get; set; }
            public virtual User Approver { get; set; }
    public int ApproverID { get; set; }
    public int EvaluatorID { get; set; }
    public int ElaboratorID { get; set; }

    So, when I need to add a new DocumentRequest, all those Users are required. So, I set the "int" properties, not the actual navigation, and when I call  context.DocumentRequests.Add(obj) and context.SaveChanges() it fails, because it tries to add all the objects. The Users are already in the database, I don't want to add them, they already exist.

    I even tried to call document.Approver = context.Users.Find(document.ApproverID), but it also tries to add the approver, even though I just fetched it. I tried to set the state context.Entry<User>(document.Approver).State = EntityState.Unchanged, but it does not work. It's like entity overrides this and is always Added.

    What can I do?

    Take a look at WPF FlashMessage

    • Edited by Joba Diniz Tuesday, January 28, 2014 6:11 PM
    Tuesday, January 28, 2014 6:06 PM

All replies

  • Hello,

    How do you define the exact navigation relationship? Could you please share it with use?

    >>So, when I need to add a new DocumentRequest, all those Users are required.

    Have a try to define these foreign keys to be nullable as below using HasOptional:

    modelBuilder.Entity<DocumentRequest>().HasOptional<User>(p => p. Approver).WithMany().WillCascadeOnDelete(false);

    And we need to change these properties to be string type since int type cannot be nullable:

    public string ApproverID { get; set; }

    When adding a new entity into DocumentRequests as below:

    DocumentRequest docu = new DocumentRequest() { Id = "2", Name = "2", ApproverID = "1" };

    It then does not require all objects.

    If I misunderstand, please let me know.


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Wednesday, January 29, 2014 8:08 AM
  • I made it work by fetching the Users and adding then to the properties, like:

    documentRequest.Approver = context.Users.Find(documentRequest.ApproverID);
                    documentRequest.Customer = context.Users.Find(documentRequest.CustomerID);
                    documentRequest.Elaborator = context.Users.Find(documentRequest.ElaboratorID);
                    documentRequest.Evaluator = context.Users.Find(documentRequest.EvaluatorID);

    However, is there a way to only set the ids properties (ApproverID, CustomerID, etc) and the EF fetch the data for me, setting the Approver, Customer properties?

    Take a look at WPF FlashMessage

    Wednesday, January 29, 2014 11:36 AM
  • Hello,

    >>However, is there a way to only set the ids properties (ApproverID, CustomerID, etc) and the EF fetch the data for me, setting the Approver, Customer properties?

    Felling quite confused what it means. Could you please describe it more clearly.


    Monday, February 3, 2014 9:18 AM
  • Look at this code:

    public void Save(DocumentRequest documentRequest)
                if (documentRequest.DocumentRequestID == 0)
                    documentRequest.Approver = context.Users.Include("Person").First(d => d.UserID == documentRequest.ApproverID);
                    documentRequest.Customer = context.Users.Include("Person").First(d => d.UserID == documentRequest.CustomerID);
                    documentRequest.Elaborator = context.Users.Include("Person").First(d => d.UserID == documentRequest.ElaboratorID);
                    documentRequest.Evaluator = context.Users.Include("Person").First(d => d.UserID == documentRequest.EvaluatorID);
                    logger.Logger(Actions.Insert, "DocumentRequest", documentRequest);
                    DocumentRequest dbEntry = context.DocumentRequests.Find(documentRequest.DocumentRequestID);
                    if (dbEntry != null)
                        dbEntry.ApproverID = documentRequest.ApproverID;
                        dbEntry.EvaluatorID = documentRequest.EvaluatorID;
                        dbEntry.ElaboratorID = documentRequest.ElaboratorID;
                        dbEntry.Description = documentRequest.Description;
                        dbEntry.LimitDate = documentRequest.LimitDate;
                        dbEntry.Title = documentRequest.Title;
                        dbEntry.DocumentID = documentRequest.DocumentID;
                        dbEntry.RequestType = documentRequest.RequestType;
                        dbEntry.Progress = documentRequest.Progress;
                        dbEntry.Step = documentRequest.Step;
                        logger.Logger(Actions.Update, "DocumentRequest", documentRequest);
                    documentRequest.Document = context.Documents.Find(dbEntry.DocumentID);
                    documentRequest.Approver = context.Users.Include("Person").First(d => d.UserID == dbEntry.ApproverID);
                    documentRequest.Customer = context.Users.Include("Person").First(d => d.UserID == dbEntry.CustomerID);
                    documentRequest.Elaborator = context.Users.Include("Person").First(d => d.UserID == dbEntry.ElaboratorID);
                    documentRequest.Evaluator = context.Users.Include("Person").First(d => d.UserID == dbEntry.EvaluatorID);

    In the INSERT, I need to populate the relationships before saving... if I do not, an error is raised.

    In the UPDATE, I need to populate the relationships after, because they are all null, and I will need them to be populated after the save.

    Take a look at WPF FlashMessage

    Wednesday, February 5, 2014 12:24 PM