使用 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;
}
}
结果
我需要为财务会计 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;
}
}
结果