如何在嵌套响应中获得一对多关系的多实体?

时间:2018-12-12 13:20:58

标签: c# entity-framework entity-framework-core

我上了一堂电影

public class Movie
    {

        public int Id { get; set; }
        public string Name { get; set; }
        public Producer ProducerName { get; set; }
    }

和一个班级制作人

public class Producer
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public ICollection<Movie> Movies { get; set; }
    }

从制作人到电影,他们之间存在一对多的关系,即一个制作人可以拥有多部电影,而一部电影只有一个制作人。

我通过以下查询获取电影详细信息。

var result = _context.Movies
                    .Include(m => m.ProducerName)
                    .ToList();

我低于Json:

{
        "id": 1,
        "name": "Venom",
        "producerName": {
            "id": 2,
            "name": "Amy Pascal",
            "movies": [
                {
                    "id": 1,
                    "name": "Venom"
                }
            ]
        }
    }

我要在同一查询中与制作人相关联的所有电影吗?

{
            "id": 1,
            "name": "Venom",
            "producerName": {
                "id": 2,
                "name": "Amy Pascal",
                "movies": [
                    {
                        "id": 1,
                        "name": "Venom"
                    },
                    {
                        "id": 56,
                        "name": "something"
                    },
                    {
                        "id": 81,
                        "name": "else"
                    }
                ]
            }
        }

我该怎么做?

编辑:在一个答案中使用查询,我只收到制作人的一部电影(当前电影),而不是全部。 我看到了数据库,发现即使从制作人到电影这是一对多的关系,对于同一个制作人也要插入多行(具有不同的主键)。我的问题在这里有所不同。我正在使用json播种数据库。 ID(PK)是数据库生成的。

用于种子数据库的JSON:

[   
  {
    "Name": "Venom",
    "ProducerName": 
          {
               "Name": "Steven Spielberg"
          }   
  },
  {
    "Name": "Kung Fu League",
    "ProducerName":
          {
               "Name": "Steven Spielberg"
          }  
  }
]

如何限制EF Core不能为同一生产者创建重复的行,而不为同一生产者生成不同的密钥,否则我可能会成功接收单个生产者的所有电影?

1 个答案:

答案 0 :(得分:2)

您可以链接包括。首先从Movies开始,然后从Include Producers开始,最后使用ThenInclude包括制片人的电影。

更新

如@Gert Arnold在投影(不返回实体)时指出的那样,EF Core Includes are ignored则这样,如果我选择投影到其他东西,则可以删除Includes。 / p>

所以:

// use .Include and .ThenInclude when returning your entities
var returningEntities = context.Movies
                                 .Include(p => p.ProducerName)
                                 .ThenInclude(m => m.Movies).ToList();

// No need for Include when use projection
var returningAnonymousObject = context.Movies
    .Select(a => new
    {
        id = a.Id,
        name = a.Name,
        producer = new
        {
            id = a.ProducerName.Id,
            name = a.ProducerName.Name,
            movies = a.ProducerName.Movies.Select(m => new
            {
                id = m.Id,
                name = m.Name
            })
        }
    }).ToList();