使用 entity framework 核心排除自我相关 table 的重复结果

Exclude duplicate results from self related table using entity framework core

我需要为财务会计 web-api 软件的帐户创建分层树我创建了一个 table 具有自我关系但得到重复记录。

数据模型:

public class Account
{
    public int AccountId { get; set; }

    public int AccountCode { get; set; }

    [Required]
    public string AccountName { get; set; }
    
    public int AccountParentCode { get; set; }
    public int? AccountParentId { get; set; }

    [IgnoreDataMember]
    public Account AccountParent { get; set; }
            
    public ICollection<Account> AccountChields { get; set; }
}

return 值到 api:

return _context.Accounts.ToListAsync();

我的输出:

    [  {
    "accountId": 147,
    "accountCode": 1,
    "accountName": "Test1",
    "accountParentCode": 0,
    "accountParentId": null,
    "accountChields": [
      {
        "accountId": 149,
        "accountCode": 11,
        "accountName": "Test11",
        "accountParentCode": 1,
        "accountParentId": 147,
        "accountChields": [
          {
            "accountId": 152,
            "accountCode": 113,
            "accountName": "Test113",
            "accountParentCode": 11,
            "accountParentId": 149,
            "accountChields": null
          },
          {
            "accountId": 153,
            "accountCode": 114,
            "accountName": "Test114",
            "accountParentCode": 11,
            "accountParentId": 149,
            "accountChields": null
          },
          {
            "accountId": 154,
            "accountCode": 115,
            "accountName": "Test115",
            "accountParentCode": 11,
            "accountParentId": 149,
            "accountChields": null
          }
        ]
      },
      {
        "accountId": 150,
        "accountCode": 16,
        "accountName": "Test16",
        "accountParentCode": 1,
        "accountParentId": 147,
        "accountChields": null
      },
      {
        "accountId": 151,
        "accountCode": 18,
        "accountName": "Test18",
        "accountParentCode": 1,
        "accountParentId": 147,
        "accountChields": null
      }
    ]
  },
  {
    "accountId": 148,
    "accountCode": 2,
    "accountName": "Test2",
    "accountParentCode": 0,
    "accountParentId": null,
    "accountChields": null
  },
  {
    "accountId": 149,
    "accountCode": 11,
    "accountName": "Test11",
    "accountParentCode": 1,
    "accountParentId": 147,
    "accountChields": [
      {
        "accountId": 152,
        "accountCode": 113,
        "accountName": "Test113",
        "accountParentCode": 11,
        "accountParentId": 149,
        "accountChields": null
      },
      {
        "accountId": 153,
        "accountCode": 114,
        "accountName": "Test114",
        "accountParentCode": 11,
        "accountParentId": 149,
        "accountChields": null
      },
      {
        "accountId": 154,
        "accountCode": 115,
        "accountName": "Test115",
        "accountParentCode": 11,
        "accountParentId": 149,
        "accountChields": null
      }
    ]
  },
  {
    "accountId": 150,
    "accountCode": 16,
    "accountName": "Test16",
    "accountParentCode": 1,
    "accountParentId": 147,
    "accountChields": null
  },
  {
    "accountId": 151,
    "accountCode": 18,
    "accountName": "Test18",
    "accountParentCode": 1,
    "accountParentId": 147,
    "accountChields": null
  },
  {
    "accountId": 152,
    "accountCode": 113,
    "accountName": "Test113",
    "accountParentCode": 11,
    "accountParentId": 149,
    "accountChields": null
  },
  {
    "accountId": 153,
    "accountCode": 114,
    "accountName": "Test114",
    "accountParentCode": 11,
    "accountParentId": 149,
    "accountChields": null
  },
  {
    "accountId": 154,
    "accountCode": 115,
    "accountName": "Test115",
    "accountParentCode": 11,
    "accountParentId": 149,
    "accountChields": null
  }
]

我是 .Net 技术的新手,有没有办法完成这项任务,或者我是否必须改变我对设置数据库的想法?

谢谢你;

最好清理数据库中的数据,但您可以使用此代码排除重复数据:

 _context.Accounts.Distinct().ToListAsync();

a table with self relationship but get duplicate records

可以先找到所有的根元素,然后依次找到对应的子元素

此外,您不需要 AccountParentCode 属性,您可以获取ParentCode 父元素 通过 AccountParent

下面是例子,大家可以参考一下

控制器

[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
    public DailyCoreMVCDemoContext db;
    public ValuesController(DailyCoreMVCDemoContext _db)
    {
        db = _db;
    }
    [HttpGet]
    public async Task<string> test()
    {
        var allrootAccount = await db.Accounts.Where(m => m.AccountParentId == null).ToListAsync();
        var test = await db.Accounts.ToListAsync();
        allrootAccount.ForEach(t =>
        {
            t.AccountChields = GetSubordinateAccounts(test, t);
        });
        string result = JsonConvert.SerializeObject(allrootAccount, Formatting.None,
                    new JsonSerializerSettings()
                    {
                        ReferenceLoopHandling = ReferenceLoopHandling.Ignore
                    });
        return result;
    }
    //a recursive method to get all subordinate Accounts
    public static List<Account> GetSubordinateAccounts(List<Account> allAccounts, Account superordinateAccount)
    {
        var result = new List<Account>();
        var subordinate = allAccounts.Where(a => a.AccountParentId == superordinateAccount.AccountId & a.AccountId != a.AccountParentId).ToList();
        if (subordinate.Count != 0)
        {
            result.AddRange(subordinate);
            foreach (var subo in subordinate)
            {
                result.AddRange(GetSubordinateAccounts(subordinate, subo));
            }
        }
        return result;
    }
}

结果