0

I'm making project about having 2 or more people can make an appointment to each other. everything work fine, but I just realize that some data from foreign key automatically loaded even though I didn't include it in code.

This is the result from API that I made

{
    "uId": 1,
    "userId": "xxxx",
    "receiveAppointmentForms": [],
    "requestAppointmentForms": [
        {
            ...Some infomation,
            "receiveUser": {
                "uId": 2,
                "userId": "zzz",
                "receiveAppointmentForms": [],
                "requestAppointmentForms": null,
                "topThrees": null,
                "userRole": null,
                "coach": null,
                "department": null,
                "position": null
            },
            "record": null
        }
    ],
    "userRole": null,
    "coach": null,
    "department": null,
    "position": null
},

So I did include "requestAppointmentForms" field, but I don't want the "receiveUser", which is the foreign key refers to the User table, to be shown. because I didn't use that information on my web page and it makes the request slower cause it has a lot of data.

Here is my code on the controller

[HttpGet]
public IEnumerable<User> GetUsers()
{
    return _context.Users.Include( r => r.ReceiveAppointmentForms)
                          .Include(r => r.RequestAppointmentForms);
}

Code from appointmentform model

    [Key]
    public int AppointmentFormId { get; set; }
    public string AppointmentDate { get; set; }
    public DateTime AppointmentDateRequest { get; set; }
    public string AppointmentTimeStart { get; set; }
    public string AppointmentStatus { get; set; }
    public string AppointmentCancelComment { get; set; }

    public int? RequestUserId { get; set; }
    public int? ReceiveUserId { get; set; }

    public User RequestUser { get; set; }

    public User ReceiveUser { get; set; }
    public AppointmentRecord Record { get; set; }
Patrick
  • 734
  • 11
  • 26

2 Answers2

0

One thing you can do while you want to send data with API is creating a new class. it is safe and you can send any data that you only want. (ViewModels)

if you use your entities directly WebAPI will model bind all parameters to them, even if you didn't want to. my suggestion is to create a new model then send your data

public class UserViewModel
{
    public int AppointmentFormId { get; set; }
    public string AppointmentDate { get; set; }
    public DateTime AppointmentDateRequest { get; set; }  
    //Your other data and tables you want
}

Now call your Api Will be like this

[HttpGet]
public IEnumerable<UserViewModel> GetUsers()
{
IEnumerable<UserViewModel> usersList = new List<UserViewModel>();
foreach (var item in _context.Users.tolist())
{
userList.add(new UserViewModel{
AppointmentFormId  = item.AppointmentFormId ,
//other data
});
}

It is easy and secure!

you can check this link for more information

Shervin Ivari
  • 1,759
  • 5
  • 20
  • 28
0

This is default behaivor for loop referencing.

Entity Framework Core will automatically fix-up navigation properties to any other entities that were previously loaded into the context instance. So even if you don't explicitly include the data for a navigation property, the property may still be populated if some or all of the related entities were previously loaded.

Reference: Eager loading.

For ignoring the receiveUser, you could try

services.AddMvc()
    .AddJsonOptions(opt => {
        opt.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
    }).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

Or, you may create ViewModel and try AutoMapper to map entity to viewmodel.

Edward
  • 28,296
  • 11
  • 76
  • 121