问题描述
我需要从财务会计 web-api 软件的帐户创建分层树我创建了一个具有自我关系的表,但得到了重复的记录。
数据模型:
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; }
}
返回值给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",{
"accountId": 154,"accountCode": 115,"accountName": "Test115","accountChields": null
}
]
},{
"accountId": 150,"accountCode": 16,"accountName": "Test16","accountChields": null
},{
"accountId": 151,"accountCode": 18,"accountName": "Test18","accountChields": null
}
]
},{
"accountId": 148,"accountCode": 2,"accountName": "Test2","accountChields": null
},{
"accountId": 149,"accountChields": [
{
"accountId": 152,{
"accountId": 153,{
"accountId": 154,{
"accountId": 150,{
"accountId": 151,{
"accountId": 152,{
"accountId": 153,{
"accountId": 154,"accountChields": null
}
]
我刚开始使用 .Net 技术,有没有办法完成这项任务,或者我是否必须改变我对设置数据库的看法?
谢谢;
解决方法
最好清理数据库中的数据,但您可以使用此代码排除重复数据:
_context.Accounts.Distinct().ToListAsync();
,
有自我关系但得到重复记录的表
可以先找到所有的根元素,然后依次找到对应的子元素。
另外,你不需要AccountParentCode属性,你可以通过AccountParent获取父元素的ParentCode /strong>。
下面是一个例子,你可以参考一下。
控制器
[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;
}
}