实体框架核心:包括中断Http响应

时间:2018-02-10 20:51:07

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

我遇到了在Entity Framework Core和Asp .NET Core中建立一个简单的多对多关系的问题,这让我发疯了。每当我尝试使用Includes()方法返回相关集合时,我的HTTP响应就会中断。有人可以帮帮我吗?

快速演示,这是Product和Category类之间的简单关系:

public class Product
{
    public int ProductId { get; set; }
    public string Name { get; set; }
    public ICollection<ProductCategory> ProductCategories { get; set; }
}

public class Category
{
    public int CategoryId { get; set; }
    public string Name { get; set; }
    public ICollection<ProductCategory> ProductCategories { get; set; }
}

public class ProductCategory
{
    public int ProductId { get; set; }
    public int CategoryId { get; set; }
    public Product Product { get; set; }
    public Category Category { get; set; }
}

实体框架DbContext:

public class ProductDbContext : DbContext
{
    public DbSet<Product> Products { get; set; }
    public DbSet<Category> Categories { get; set; }
    public DbSet<ProductCategory> ProductCategories { get; set; }

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

    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<ProductCategory>().HasKey(s => new { s.ProductId, s.CategoryId });

        base.OnModelCreating(modelBuilder);
    }
}

一个带有Set方法的控制器(只是一种快速播种数据的方法)和一个Get方法来实际获得结果:

public class ProductController : Controller
{
    ProductDbContext _context;

    public ProductController(ProductDbContext context)
    {
        _context = context;
    }

    public IActionResult Set()
    {
        _context.Products.AddRange(
            new Product
            {
                Name = "TestProduct1"
            },
            new Product
            {
                Name = "TestProduct2"
            }
            );

        _context.Categories.AddRange(
            new Category
            {
                Name = "TestCategory1"
            },
            new Category
            {
                Name = "TestCategory2"
            }
            );

        _context.SaveChanges();

        _context.ProductCategories.AddRange(
            new ProductCategory
            {
                ProductId = 1,
                CategoryId = 1
            },
            new ProductCategory
            {
                ProductId = 2,
                CategoryId = 1
            },
            new ProductCategory
            {
                ProductId = 2,
                CategoryId = 2
            }
            );

        _context.SaveChanges();

        return Ok();
    }

    public IActionResult Get()
    {
        var products = _context.Products
            //.Include(p => p.ProductCategories)
            .ToList();
        return Ok(products);
    }
}

要测试,首先我通过Postman(http://localhost:54551/product/set)点击Set方法。在此之后,点击Get方法(http://localhost:54551/product/get)将返回:

[
    {
        "productId": 1,
        "name": "TestProduct1",
        "productCategories": null
    },
    {
        "productId": 2,
        "name": "TestProduct2",
        "productCategories": null
    }
]

然而,取消注释Get方法中的Includes调用给了我:

无法得到任何回复

There was an error connecting to http://localhost:54551/product/get.
Why this might have happened:
The server couldn't send a response:
Ensure that the backend is working properly
Self-signed SSL certificates are being blocked:
Fix this by turning off 'SSL certificate verification' in Settings > General
Proxy configured incorrectly
Ensure that proxy is configured correctly in Settings > Proxy
Request timeout:
Change request timeout in Settings > General

我失踪的是什么?我有CORS设置允许任何来源。如果我在return Ok(products)上设置断点并且Includes()调用未注释,我可以看到数据正被添加到products对象。

为什么响应会失败?

1 个答案:

答案 0 :(得分:5)

这是json序列化程序的循环引用问题。 您可以通过在Startup.cs文件中添加以下配置来解决此问题:

services.AddMvc()
    .AddJsonOptions(option =>
    {
        option.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
    });