0

I'm working on a messaging platform type sales platform. A buyer can contact a seller about a product. Their message concerns a specific product.

The exchange of messages is only possible between a buyer and the owner of the product, and will only concern the product in question.

The exchanges are recorded in a database.

This is the model - columns User_Exp, User_Dest and Article are foreign keys

 public class MessagesModel
 { 
    public long Id { get; set; } 
    public ApplicationUser User_Exp { get; set; } 
    public ApplicationUser User_Dest { get; set; } 
    public Articles Article { get; set; }

    public string Message { get; set; } 
    public messageStatus Status { get; set; } 
    public DateTime Created_at { get; set; } 

    public enum messageStatus
    {
        Sent,
        Delivered
    } 

    public MessagesModel() 
    {
        Status = messageStatus.Sent;
    } 
}

When loading the "Messages" view, I retrieve the exchange history:

function getChat ( )  { 
        $.ajax ( { 
            url: '@Url.Action("ConversationWithContact", "Messaging")' ,
            type: 'GET' ,
            cache: false ,
            data: { articleId:   '@Html.DisplayTextFor(model => model.Id)' } ,
         } ) 
            .done ( function ( resp )  { 
            var chat_data = resp.data || [ ] ;
            loadChat ( chat_data ) ;
             } ) ;
     } ;

The controller code:

    public JsonResult ConversationWithContact(long articleId) 
    { 
        ApplicationUser currentUser = _repo.GetUser();
        Articles item = _repo.GetArticleByID(articleId);

        var conversations = new List<Models.Messages.MessagesModel> ( ) ;

        conversations = _context.Messages
                                .Where(c => (c.Article.Id == item.Id) 
                                            && (c.User_Dest.Id == currentUser.Id ||
                                                c.User_Exp.Id == currentUser.Id)) 
                                .OrderBy(c => c.Created_at) 
                                .ToList();

        return Json (new { status = "success", data = conversations });
    }

This is where the problem shows up.

For the example I have 2 users, Titi and Toto, and a salesperson. Titi and Toto each sent a message to the salesperson about the same product.

conversations returns NULL for User_Exp while the value is present in the database.

The problem occurs in the controller:

enter image description here

This happens for every message for which the user using the messaging is not the sender.

When it is the RECIPIENT (in this case the product owner) who uses the messaging, each User_Exp is NULL:

enter image description here

For Titi, it is Toto's messages that have user_Exp = NULL:

enter image description here

And for Toto, it is Titi's messages:

enter image description here

I absolutely need the user_Exp info to then sort the messages.

I can't understand this problem. Maybe it's just a logic problem, but I don't understand it.

Thanks

6
  • 1
    It looks like that User_Exp is a navigation property. If you want to return it, you need to ensure it is eager loaded. Serializing entities to send to the View is generally not a good idea as the view (browser) is not dealing with "entities" as much as just form data, and the entities end up transporting far more info than the view ever needs. Instead, consider projecting to a ViewModel using Select() or a mapping provider like AutoMapper. This negates worrying about whether data is eager loaded or not, and helps produce far more efficient queries. Commented Oct 27 at 5:26
  • Thank you for these suggestions. However, there doesn't seem to be a problem related to the view. The issue is that the data is incomplete in the controller. Commented Oct 27 at 9:00
  • Did you try eager loading the User_Exp?? (Add .Include(c => c.User_Exp) to your query [in the controller]) Commented Oct 27 at 20:28
  • I did it 5 minutes before reading your message! :) Unfortunately, it didn't change anything. _context.Messages.Include(c => c.User_Exp); _context.Messages.Include(c => c.User_Dest); conversations = _context.Messages. Where(c => (c.Article.Id == item.Id) && (c.User_Dest.Id == currentUser.Id || c.User_Exp.Id == currentUser.Id)) .OrderBy(c => c.Created_at) .ToList(); Commented Oct 27 at 21:58
  • .Include() needs to be part of the query. calling _context.Messages.Include(...) on its own won't do anything. I put the updated query expression that should give you the data you expect in an answer below. Commented Oct 28 at 4:54

1 Answer 1

2

To eager load the related data, the .Include() statements need to be part of the query expression:

conversations = _context.Messages
    .Include(c => c.User_Exp)
    .Include(c => c.User_Dest)
    .Where(c => (c.Article.Id == item.Id)
        && (c.User_Dest.Id == currentUser.Id || c.User_Exp.Id == currentUser.Id))                                 
    .OrderBy(c => c.Created_at)
    .ToList();
Sign up to request clarification or add additional context in comments.

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.