神秘消失的实体协会

时间:2016-10-11 12:52:44

标签: c# .net entity-framework

我有一个长时间运行的功能,它覆盖了我的CompaniesHouseRecords条记录,并通过我的CompanySearch()方法从API获得匹配的CompaniesHouseRecords。此方法进行Json API调用并返回detatched CompanySearch()列表(CompaniesHouseRecord方法不创建任何数据库上下文。)

然后检查Company是否存在。如果它实例化它,如果它不实例化我将它添加到数据库,所以它获取一个ID,并由上下文跟踪。

然后我检查CompaniesHouseRecord记录是否包含此CompaniesHouseRecord,如果不包含,则添加关联。

一切似乎都很好。通常,每次搜索都返回20 CompaniesHouseRecords。经过一段时间后,我注意到开头的记录丢失了CompaniesHouseRecords

我重置了标志并再次运行循环。所有CompaniesHouseRecord仍然存在但在此传递中它重新关联所有缺失的那些。过了一会儿,一开始就失去了联想。

我猜测发生的事情是一个名称相似的公司在其搜索结果中包含相同的CompaniesHouseRecord,当它被分配给一个公司时,它会从另一个公司中删除它。我添加了一个流畅的api多对多映射,但问题仍然存在。 (数据库中有CompanyCompaniesHouseRecord表)

我编写了一个测试函数,尝试将Companies与多个CompaniesHouseRecords相关联,并且工作正常。我还在数据库上运行了一个查询,以带回所有Company个有public static void CheckCompanyRecords() { int count = 0; int total = 0; using (var db = new PlaceDBContext()) { total = db.Companies .Where(x => x.CheckedCompaniesHouse == false) .Count(); } while (count < total) { using (var db = new PlaceDBContext()) { var toCheck = db.Companies .Include(x => x.CompaniesHouseRecords) .Where(x => x.CheckedCompaniesHouse == false) .OrderBy(x => x.ID) .Skip(count) .Take(10) .ToList(); foreach (var company in toCheck) { Messages.Output("Searching for: " + company.Name); List<CompaniesHouseRecord> chrl = CompanySearch(company.Name).Result; Messages.Output("Found : " + chrl.Count().ToString()); int added = 0; int exist = 0; int assigned = 0; if (chrl.Count() > 0) { foreach (var chr in chrl) { //initiate chr record CompaniesHouseRecord foundCompany; if (db.CompaniesHouseRecords.Any(x => x.CompanyNumber == chr.CompanyNumber)) { foundCompany = db.CompaniesHouseRecords.Single(x => x.CompanyNumber == chr.CompanyNumber); exist++; } else { foundCompany = chr; db.CompaniesHouseRecords.Add(foundCompany); added++; } //add and then save if its not already associated if (!company.CompaniesHouseRecords.Any(x => x.ID == foundCompany.ID)) { company.CompaniesHouseRecords.Add(foundCompany); assigned++; } } } company.CheckedCompaniesHouse = true; db.SaveChanges(); count++; Messages.Output("Added New : " + added.ToString()); Messages.Output("Already Exist: " + exist.ToString()); Messages.Output("Assigned : " + assigned.ToString()); Messages.Output(""); } } } } 个记录的CompaniesHouseRecord,我可以看到有多个关系的植物,所以看起来添加多个引用没有问题但是出于某种原因,每次进程运行时,一段时间后,开头记录的关联开始消失。

这一定是我的逻辑问题,但我看不到它。这个过程需要很长时间才能运行,所以这需要花费几天的时间来弄清楚。

这是方法,任何人都可以看到为什么关联会消失?

CompanyNumber

编辑:

因此,我查看了正在重新分配的ID,它们非常高,如600,000 id,但它们应该具有较低的ID,因为它们是第一个要添加的ID。

这似乎表明,在某些时候,现有的[StringLength(100)] [Index(IsUnique = true)] public string CompanyNumber { get; set; } 会被删除并创建一条新记录,但没有现有的关联,但我的代码中什么也看不到会这样做。

我唯一能想到的是Microsoft.VsHub.Server.HttpHostx64.exe不是唯一的,但我在实体类中强制执行此操作:

{{1}}

编辑:

我让进程在调试中运行了几个小时,发现{{1}}占用了2GB的内存。如果我让它停止运行太久,我的debgging会话会抛出超时或outofmemory异常。

我想知道这是否会以某种方式导致意外行为,或者它是否只发生在调试会话中?

1 个答案:

答案 0 :(得分:1)

由于新添加的foundCompany条目在ID被调用之前未设置db.SaveChanges(),因此可能会发生以下情况:

第一次,!company.CompaniesHouseRecords.Any(x => x.ID == foundCompany.ID)应该对每家公司评估为真。但是,以下所有情况都会在比较的两边使用0null作为ID进行评估,因此不会添加它们。

确保对尚未保存的实体使用适当的比较条件,或者在使用其ID之前保存中间结果(似乎您已在评论后尝试成功)。许多保存的替代方法可能是将company.CompaniesHouseRecords.Add(foundCompany);无条件地移动到else块中,并将条件Add嵌套到现有if-then条目的foundCompany块中被检索。