Web API加载相关数据

时间:2018-07-24 09:27:29

标签: c# entity-framework asp.net-core-webapi

我正在使用ASP CORE 2.1和EF CORE创建带有2个数据表和1个ForeignKey的Web API

型号:

 public partial class AuditInfo
{

    public int Id { get; set; }
    public string Level { get; set; }
    public string Period { get; set; }
    public string Auditor { get; set; }

    public virtual ICollection<Item> Items { get; set; }
}

  public partial class Item
{
    public int Id { get; set; }
    public string Ponumber { get; set; }
    public bool IsComplete { get; set; }

    public AuditInfo AuditInfo { get; set; }
}

public partial class VEDHOMEContext : DbContext
{
    public VEDHOMEContext()
    {

    }

    public VEDHOMEContext(DbContextOptions<VEDHOMEContext> options)
        : base(options)
    {

    }

    public virtual DbSet<AuditInfo> AuditInfo { get; set; }
    public virtual DbSet<Item> Item { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {




    }

     protected override void OnModelCreating(ModelBuilder modelBuilder)
    {

        modelBuilder
            .HasAnnotation("ProductVersion", "2.1.1-rtm-30846")
            .HasAnnotation("Relational:MaxIdentifierLength", 128)
            .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);

        modelBuilder.Entity("auditAPI.Models.AuditInfo", b =>
        {
            b.Property<int>("Id")
                .ValueGeneratedOnAdd()
                .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);

            b.Property<string>("Auditor");

            b.Property<string>("Level");

            b.Property<string>("Period");

            b.HasKey("Id");

            b.ToTable("AuditInfo");
        });

        modelBuilder.Entity("auditAPI.Models.Item", b =>
        {
            b.Property<int>("Id")
                .ValueGeneratedOnAdd()
                .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);

            b.Property<int?>("AuditInfoId");

            b.Property<bool>("IsComplete");

            b.Property<string>("Ponumber");

            b.HasKey("Id");

            b.HasIndex("AuditInfoId");

            b.ToTable("Item");
        });

        modelBuilder.Entity("auditAPI.Models.Item", b =>
        {
            b.HasOne("auditAPI.Models.AuditInfo", "AuditInfo")
                .WithMany("Items")
                .HasForeignKey("AuditInfoId");
        });


    }



}

控制器:

[Route("api/[controller]")]
[ApiController]
public class AuditInfoesController : ControllerBase
{
    private readonly VEDHOMEContext _context;

    public AuditInfoesController(VEDHOMEContext context)
    {
        _context = context;
    }

    // GET: api/AuditInfoes
    [HttpGet]
    public IEnumerable<AuditInfo> GetAuditInfo()
    {
        return _context.AuditInfo;
    }

    // GET: api/AuditInfoes/5
    [HttpGet("{id}")]
    public async Task<IActionResult> GetAuditInfo([FromRoute] int id)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        var auditInfo = await _context.AuditInfo.FindAsync(id);

        if (auditInfo == null)
        {
            return NotFound();
        }

        return Ok(auditInfo);
    }

    // PUT: api/AuditInfoes/5
    [HttpPut("{id}")]
    public async Task<IActionResult> PutAuditInfo([FromRoute] int id, [FromBody] AuditInfo auditInfo)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        if (id != auditInfo.Id)
        {
            return BadRequest();
        }

        _context.Entry(auditInfo).State = EntityState.Modified;

        try
        {
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!AuditInfoExists(id))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }

        return NoContent();
    }

    // POST: api/AuditInfoes
    [HttpPost]
    public async Task<IActionResult> PostAuditInfo([FromBody] AuditInfo auditInfo)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        _context.AuditInfo.Add(auditInfo);
        await _context.SaveChangesAsync();

        return CreatedAtAction("GetAuditInfo", new { id = auditInfo.Id }, auditInfo);
    }

    // DELETE: api/AuditInfoes/5
    [HttpDelete("{id}")]
    public async Task<IActionResult> DeleteAuditInfo([FromRoute] int id)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        var auditInfo = await _context.AuditInfo.FindAsync(id);
        if (auditInfo == null)
        {
            return NotFound();
        }

        _context.AuditInfo.Remove(auditInfo);
        await _context.SaveChangesAsync();

        return Ok(auditInfo);
    }

    private bool AuditInfoExists(int id)
    {
        return _context.AuditInfo.Any(e => e.Id == id);
    }
}

但是我得到与项目相关的数据返回null,我该如何解决? 我是这个框架的新手,非常感谢您的帮助。

[{"id":1,"level":"level1","period":"jan","auditor":"A","items":null},{"id":2,"level":"level2","period":"feb","auditor":"B","items":null}]

预期输出:

[{"id":1,"level":"level1","period":"jan","auditor":"A","items":{"Id":1,"Ponumber":"0001","IsComplete":"True","AuditInfoId":1},{"id":2,"Ponumber":"0002","IsComplete":"True","AuditInfoId":1}}]

对于有类似问题的人,我通过添加

来解决
services.AddMvc()
.AddJsonOptions(options => {
    options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
});

和编辑控制器

public async Task<List<AuditInfo>> GetAuditInfo()
    {
        //return _context.AuditInfo;
        var infoes = await _context.AuditInfo.Include(a => a.Items).ToListAsync();
        return infoes;

    }

1 个答案:

答案 0 :(得分:3)

我不确定您是否看到过对此question的可接受的答案,但是问题在于JSON序列化程序如何处理循环引用。完整的详细信息和更多参考的链接可以在上面的链接中找到,我建议进行深入研究,但是总之,在age中添加以下内容将使序列化程序配置为忽略循环参考:

BaseClass