Ahmed Mujtaba Ahmed Mujtaba - 1 month ago 5x
C# Question

Object doesn't add with children - EF Code First

It's been quite a while since I last used EF. I've never had any problems using it before. Now I'm attempting to insert an object that has a one-many relationship with another object. But in the API call, the collection array of the child object is shown to be empty however the parent object can be seen in the api call of the child object.

I have my models as below:

Conversation Table

public class Conversation
public Conversation()
this.ChatMessages = new List<ChatMessage>();
this.DeletedConversations = new List<ConversationDeleted>();
public int ConversationID { get; set; }
public string toUser { get; set; }
public string FromUser { get; set; }

public ICollection<ChatMessage> ChatMessages { get; set; }
public ICollection<ConversationDeleted> DeletedConversations { get; set; }
public DateTime CreatedAt { get; set; }
public int UserID { get; set; }

ChatMessage Table

public class ChatMessage
public int ChatMessageID { get; set; }
public string fromUser { get; set; }
public string toUser { get; set; }
public string Message { get; set; }
public bool DeliveryStatus { get; set; }
public DateTime CreatedAt { get; set; }
public Guid UniqueID { get; set; }
public int ConversationID { get; set; }

public virtual Conversation Conversation { get; set; }
public ICollection<MessageDeleted> MessagesDeleted { get; set; }
public int UserId { get; set; }


My Fluent API looks like this:

.HasRequired(x => x.Conversation)
.WithMany(x => x.ChatMessages)
.HasForeignKey(x => x.ConversationID);

I'm trying to create a conversation entity and add a chat object to it's collection. I do it like so:

public IHttpActionResult CreateConversation()
ChatMessage msg = new ChatMessage { CreatedAt = DateTime.UtcNow, DeliveryStatus = true, fromUser = "annettehiggs", toUser = "terrydriscoll", Message = "Hum tum", UniqueID = Guid.NewGuid(), UserId = 43 };
Conversation conv = new Conversation();
conv.CreatedAt = DateTime.UtcNow;
conv.FromUser = "annettehiggs";
conv.toUser = "terrydriscoll";

DataModel db = new DataModel();

return Ok(conv);

and this is how I retrieve the conversation object:

public IQueryable<Conversation> GetConversations()
return db.Conversations;

As a result, ChatMessage API call shows the conversation it's associated to but the Conversation object doesn't show the chat in it's collection. What am I doing wrong here?


The add code is working properly (otherwice you'll not be able to see the new chat message). The problem is with your data retrieval code.

Since your ChatMessage.Conversation property is marked as virtual, most probably it gets lazy loaded, that's why you see it populated.

At the same time, your Conversation.ChatMessages is not virtual, hence you need to explicitly eager load it using the Inlclude method, or depending on your requirements, mark it virtual to get the lazy load behavior like the inverse navigation property.