简体   繁体   中英

Including only Id of related entity in entity framework core

I am currently developing an API with ASP.NET Core and Entity framework core with npgsql as database provider. I have two Entities and they have a one to many relation. The thing is that I only want to include the Id's of the child entity in the JSON result that the "Parent Controller" returns.

These are my entities:

public class Meal {
    public int Id { get; set; }

    public string Title { get; set; }
    public string Description { get; set; }

    public string UserId { get; set; }
    public User User { get; set; }

    public List<Picture> Pictures { get; set; }

    public Meal () {
        this.Pictures = new List<Pictures>();
    }
}

public class Picture {
    public int Id { get; set; }

    public int MealId { get; set; }
    public Meal Meal { get; set; }

    public byte[] full { get; set; }
    public byte[] small { get; set; }
}

I am however not sure on how to achieve this. Yesterday I came across another SO question which suggested something like this:

public IActionResult Meals () {
    var meal = this.context.Meals
        .Include(m => m.Pictures.Select(p => p.Id))
        .First();

    return new JsonResult(meal);
}

This however throws an InvalidOperationException. My DbContext is very basic, no onModelConfiguring because this code is following convention for as far as I know and it just has two DbSets of the corresponding types. The foreign keys are also correct in the database and callling something like:

var pictures = dbContext.Pictures.Where(p => p.MealId == mealId).ToList();

Works as expected. I have only included the code which I thought was relevant. If more is needed I will include it, but I think this is completely my limited understanding of the queries.

Thank you for your time!

You don't need to change your DB structure, one option is like so:

        var db = this.context;
        var result = (from meal in db.Meals
                      where meal.<whatever> == "123"
                      select new
                      {
                         Id = meal.Id,
                         Title = meal.Title,
                         Description = meal.Description,
                         //other required meal properties here.
                         PictureIds = meal.Pictures.Select(x => x.Id)
                      }).ToList();

You can do the same thing via lambda as well by using the "Select" method, Linq in such things seem more intuitive to me, however, to each his own... that's your choice.

.Include(m => m.Pictures.Select(p => p.Id)) will not work you have to do

.Include(m => m.Pictures)

And this will get you an array of whole picture model for you (with all properties Id, MealId,..) and in your client side you can choose Id to work with..

There is probably a better answer out there, but this is how I fixed it. Including the entire Picture class was not an option since the binary data would also be included and I did not want to query the server for the data without using it since that is an expensive call to the database.

So what I did is put the binary data in another class called PictureFile (need to think of a better name, but just File was obviously not an option). The class PictureFile just has a reference to the corresponding picture and a byte array with the picture data. That way you can include the Pictures in a Meal without getting the actual files. The client can than later decide which pictures it needs and request them by PictureId .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM