我很久以来一直坚持这个问题.
我的环境:
> Visual Studio 2017 RTM(使用此IDE的默认.net核心版本)
> Web API
> ASP.NET核心1.1
> MySQL通过Pomelo数据库提供商
我安装的包:
Microsoft.EntityFrameworkCore
Pomelo.EntityFrameworkCore.MySql
Microsoft.EntityFrameworkCore.Tools
我首先使用代码创建了3个表.
>员工:有员工名单
>申请:申请表
> EmployeeApplications:Employees和Applications的Join表
Employee和Application具有M:M关系,因此我在它们之间创建了连接表.
员工模型:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations;
namespace Test.Models
{
public class Employee
{
public int EmployeeId { get; set; }
[Required]
public string LName { get; set; }
[Required]
public string FName { get; set; }
public string Title { get; set; }
//Navigation Property
public ICollection<EmployeeApplications> EmployeeApplications { get; set; }
}
}
应用模型:
using System.Linq;
using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations;
namespace Teset.Models
{
public class Application
{
public int ApplicationId { get; set; }
[Required]
public string Name { get; set; }
public string Description { get; set; }
//Navigation Property
public ICollection<EmployeeApplications> EmployeeApplications { get; set; }
}
}
员工应用模型:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Test.Models
{
public class EmployeeApplications
{
public int EmployeeId { get; set; }
public int ApplicationId { get; set; }
public Employee Employee { get; set; }
public Application Application { get; set; }
}
}
员工控制员:
[Produces("application/json")]
[Route("api/Employees")]
public class EmployeesController : Controller
{
private readonly TestContext _context;
public EmployeesController(TestContext context)
{
_context = context;
}
// GET: api/Employees
[HttpGet]
public IEnumerable<Employee> GetEmployees()
{
return _context.Employees;
}
语境:
using Test.Models;
using Microsoft.EntityFrameworkCore;
namespace Test.Data
{
public class TestContext : DbContext
{
public TestContext(DbContextOptions<TestContext> options) : base(options)
{
}
public DbSet<Employee> Employees { get; set; }
public DbSet<Application> Applications { get; set; }
public DbSet<EmployeeApplications> EmployeeApplications { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<EmployeeApplications>()
.HasKey(c => new { c.EmployeeId, c.ApplicationId });
}
}
}
我尝试过使用.Include().当我跑去api / Employees时,我得到Postman的“无法得到任何回应”.
return _context.Employees.Include(e => e.EmployeeApplications);
我已经尝试了很多变化,但仍然没有运气.包含.Include()的任何变体都会失败.
电流输出样本:
[{
"employeeId": 1,
"lName": "Doe",
"fName": "John",
"title": "Senior Software Engineer",
"employeeApplications": null
},
{
"employeeId": 2,
"lName": "Smith",
"fName": "Jack",
"title": "Project Manager",
"employeeApplications": null
}]
我尝试使用DTO并取得了一些成功.我设法用employeeApplications中的内容替换上面的null,但是后来对Employee和Applications有了null引用.
我理想的输出:
[{
"employeeId": 1,
"lName": "Doe",
"fName": "John",
"title": "Senior Software Engineer",
"employeeApplications": [{
"applicationId": 1,
"name": "Application 1",
"description": "Description 1",
},
{
"applicationId": 2,
"name": "Application 2",
"description": "Description 2",
}]
},
{
"employeeId": 2,
"lName": "Smith",
"fName": "Jack",
"title": "Project Manager",
"employeeApplications": [{
"applicationId": 2,
"name": "Application 2",
"description": "Description 2",
},
{
"applicationId": 3,
"name": "Application 3",
"description": "Description 3",
}]
}]
基本上我想提供一份“员工”列表和他们所使用的应用程序.稍后我还要提供一份应用程序列表和处理它们的员工.
编辑:上面添加了上下文文件
编辑2:我遵循Bchir Med Amine的解决方案(目前没有工作),但后来我添加到Startup.cs的ConfigureServices方法:
services.AddMvc()
.AddJsonOptions(
options => options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
);
这让我获得了有关我的JSON的更多信息,但仍未完整. JSON现在看起来像这样:
[{
"employeeId": 1,
"lName": "Doe",
"fName": "John",
"title": "Senior Software Engineer",
"employeeApplications": [{
"employeeId": 1,
"applicationId": 1,
"application": null
},
{
"employeeId": 1,
"applicationId": 2,
"application": null
}]
},
{
"employeeId": 2,
"lName": "Smith",
"fName": "Jack",
"title": "Project Manager",
"employeeApplications": [{
"employeeId": 2,
"applicationId": 2,
"application": null
},
{
"employeeId": 2,
"applicationId": 3,
"application": null
}]
}]
应用程序现在为null.我不得不使用.Include()来生成它,但是在包含应用程序之后使用.ThenInclude()不起作用.理想的情况是打印出所有员工的清单,每个员工都应该有一份申请清单.
编辑3:我错了.ThenInclude()没有工作,是Intelisense让我失望.如果我使用.ThenInclud()我得到这个JSON:
[{
"employeeId": 1,
"lName": "Doe",
"fName": "John",
"title": "Senior Software Engineer",
"employeeApplications": [{
"employeeId": 1,
"applicationId": 1,
"application": {
"applicationId": 1,
"name": "Application 1",
"description": "Description 1",
"employeeApplications": []
}
},
{
"employeeId": 1,
"applicationId": 2,
"application": {
"applicationId": 2,
"name": "Application 2",
"description": "Description 2",
"employeeApplications": []
}
}]
},
{
"employeeId": 2,
"lName": "Smith",
"fName": "Jack",
"title": "Project Manager",
"employeeApplications": [{
"employeeId": 2,
"applicationId": 2,
"application": {
"applicationId": 2,
"name": "Application 2",
"description": "Description 2",
"employeeApplications": [{
"employeeId": 1,
"applicationId": 2,
"employee": {
"employeeId": 1,
"lName": "Doe",
"fName": "John",
"title": "Senior Software Engineer",
"employeeApplications": [{
"employeeId": 1,
"applicationId": 1,
"application": {
"applicationId": 1,
"name": "Application 1",
"description": "Description 1",
"employeeApplications": []
}
}]
}
}]
}
},
{
"employeeId": 2,
"applicationId": 3,
"application": {
"applicationId": 3,
"name": "Application 3",
"description": "Description 3",
"employeeApplications": []
}
}]
}]
第一个员工对象是Ok(仍然不理想,但它可以工作),但第二个员工不是.第二个打印出员工的应用程序,然后打印出这些应用程序的员工.
编辑4:以下是我返回JSON的方式:
return _context.Employees; //Returns just employees and '[]' for employeeApplications
return _context.Employees.Include(e => e.EmployeeApplications); //returns employees and their employeeApplications, but the applications of employeeApplications is empty
return _context.Employees.Include(e => e.EmployeeApplications).ThenInclude(ea => ea.Application); //returns everything, but continues due to circular reference
最佳答案 也许你必须将Virtual添加到类中
public class Application
{
#region Public Constructors
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Application()
{
EmployeeApplications = new HashSet<EmployeeApplications>();
}
#endregion Public Constructors
#region Public Properties
public int ApplicationId { get; set; }
public string Description { get; set; }
//Navigation Property
public virtual ICollection<EmployeeApplications> EmployeeApplications { get; set; }
[Required]
public string Name { get; set; }
#endregion Public Properties
}
public class Employee
{
#region Public Constructors
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Employee()
{
EmployeeApplications = new HashSet<EmployeeApplications>();
}
#endregion Public Constructors
#region Public Properties
//Navigation Property
public virtual ICollection<EmployeeApplications> EmployeeApplications { get; set; }
public int EmployeeId { get; set; }
[Required]
public string FName { get; set; }
[Required]
public string LName { get; set; }
public string Title { get; set; }
#endregion Public Properties
}
public class EmployeeApplications
{
#region Public Properties
public virtual Application Application { get; set; }
public int ApplicationId { get; set; }
public virtual Employee Employee { get; set; }
public int EmployeeId { get; set; }
#endregion Public Properties
}