【问题标题】:EF Core Many To Many. Error returning entitiesEF Core 多对多。返回实体时出错
【发布时间】:2018-03-23 17:39:26
【问题描述】:

我正在使用 dotnet core (2) 和 EF Core 实现 WebAPI。该应用程序使用 UnitOfWork/Repository 模式。我已经到了需要实现“多对多”关系的地步,但我遇到了一些麻烦。这是我到目前为止所得到的:

实体:

public class Team : DataEntity
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int TeamId { get; set; }

    public int OrganizationID { get; set; }

    public string Name { get; set; }

    public string URL { get; set; }

    public virtual ICollection<Season> Seasons { get; set; }

    public ICollection<TeamMember> TeamMember { get; set; }

}



public class Member : DataEntity
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int MemberId { get; set; }

    public string Name { get; set; }

    public string FirstName { get; set; }

    public string LastName { get; set; }

    public string MobilePhone { get; set; }

    public string Email { get; set; }

    public int RelatedTo { get; set; }

    public int TeamRole { get; set; }

    public ICollection<TeamMember> TeamMember { get; set; }
}



public class TeamMember
{
    public int TeamId { get; set; }
    public Team Team { get; set; }

    public int MemberId { get; set; }
    public Member Member { get; set; }
}

在我的 DbContext 类中:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<TeamMember>()
        .HasKey(t => new { t.TeamId, t.MemberId });

    modelBuilder.Entity<TeamMember>()
        .HasOne(tm => tm.Team)
        .WithMany(t => t.TeamMember)
        .HasForeignKey(tm => tm.TeamId);

    modelBuilder.Entity<TeamMember>()
        .HasOne(tm => tm.Member)
        .WithMany(t => t.TeamMember)
        .HasForeignKey(tm => tm.MemberId);

}

在我的存储库中,我对 IncludeAll 进行了扩展:

public static IQueryable<Team> IncludeAll(this IGenericRepository<Team> repository)
{
    return repository
        .AsQueryable()
        .Include(s => s.Seasons)
        .Include(tm => tm.TeamMember);

}

一切都按预期构建,但在尝试调用获取团队(我希望包括所有成员)或成员(我希望包括所有成员团队 - 上面未包含代码)的控制器操作时。 SwaggerUI 返回:TypeError:获取失败。如果我尝试直接在 chrome (http://localhost/api/Team/1) 中调用控制器操作,我会得到一个不完整的结果,但绝不会更少......结果:):

{
    "value":
    {   
        "teamId":1,
        "organizationID":1,
        "name":"Team1",
        "url":"http://www.team1.com",
        "seasons":[
            {
                "id":1,
                "teamID":1,
                "name":"PK4",
                "description":null,
                "startDate":"2017-09-01T00:00:00",
                "endDate":"2018-12-31T00:00:00",
                "created":"2017-12-01T00:00:00",
                "updated":"2017-12-27T00:00:00",
                "createdBy":"magnus",
                "updatedBy":"magnus"
            }],
        "teamMember":[
            {
                "teamId":1

我是否遗漏了一些明显的东西?

【问题讨论】:

  • 完成@GertArnold :)

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


【解决方案1】:

你的数据结构中有一个引用循环(团队 -> 团队成员 -> 团队),JSON 编码器无法处理。

我可以想到两种方法来解决这个问题:

  • 将 JSON 编码器配置为忽略引用循环

Startup.cs 中添加:

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

来自documentation

ReferenceLoopHandling.Ignore:Json.NET 将忽略引用循环中的对象并且不序列化它们。第一次遇到一个对象时,它将像往常一样被序列化,但如果遇到该对象作为其自身的子对象,则序列化程序将跳过对其进行序列化。

  • [JsonIgnore] 属性添加到您要忽略的属性中

例如:

public class TeamMember
{
    public int TeamId { get; set; }
    [JsonIgnore]
    public Team Team { get; set; }
}

【讨论】:

    【解决方案2】:

    可能与一些循环引用问题有关?!

    您的 teamMember 属性有一个 Team 属性,该属性又具有一个 teamMember 属性等等...尝试序列化时,将创建一个永无止境的循环。

    也许您可以将 teamMember.Team 属性设置为 null。我认为您还必须将 teamMember.Member.teamMember 属性设置为 null。

    【讨论】:

    • 虽然这可能是一个循环引用问题,但将 teamMember.Team 设置为 null 是个坏主意,因为实体框架会跟踪更改,任何对 SaveChanges 的调用都会产生意想不到的后果。跨度>
    猜你喜欢
    • 2020-11-20
    • 2021-05-02
    • 2020-10-01
    • 2018-02-12
    • 2021-06-10
    • 2019-03-06
    • 1970-01-01
    • 2020-11-19
    • 2020-07-14
    相关资源
    最近更新 更多