我们的应用程序中遇到了一个非常奇怪的问题,我们的实体上的导航属性最终会让人感到困惑'因为它并不认为另一端有实体,实际上存在实体。导航属性是一对一的导航,我知道我们过去曾经遇到过一对一属性的其他问题,所以也许我们只是遇到了一个奇怪的边缘案例错误?
在尝试以最简单的方式重现问题时,我发现我可以通过连续两次执行entityManager.CacheStateManager.RestoreCacheState(someCacheState)来重现它。两次这样做会导致问题,但这样做不会。在我们的应用程序中,我们正在恢复缓存状态,这似乎与问题有关。我不认为我们正在恢复它两次,但也许我们是?无论哪种方式,这样做似乎应该没问题?
此外,在我们的真实应用程序中,我可以通过在两个实体(参与一对一关系的两个实体)两次的列表上执行ImportEntities来重现该问题。在这种情况下,我不必做两次恢复相同缓存状态的奇怪事情来重现问题 - 我只是导入两次。不幸的是,我还没有能够在一个干净的解决方案中重现双重导入。
以下是一些示例代码,演示了预期的行为并显示了实际行为:
private static void TestMultipleImports()
{
//Any database with a one-to-one should work. I'm using Adventure Works here but I've modified
// it to have a one-to-one relationship. For each Contact there are 0 or 1 Contact Details
// (they both have ContactID as the Primary Key)
var mainEm = new AdventureWorksEntities();
//Add a Contact and a Contact Detail with the same SID
var contact = new Contact {ContactID = 1};
var detail = new ContactDetail {ContactID = 1};
mainEm.AttachEntity(contact);
mainEm.AttachEntity(detail);
//DevForce correctly matched up the entities so navigating from Contact to Detail or
// from Detail to Contact works as expected
Assert.AreSame(detail, contact.ContactDetail);
Assert.AreSame(contact, detail.Contact);
//In another entity manager, add the same Contact and Details
var altEm = new AdventureWorksEntities();
altEm.AttachEntity(new ContactDetail {ContactID = 1});
altEm.AttachEntity(new Contact {ContactID = 1});
//Use our helper method to import everything from our alternate EM into the main one
ImportAll(altEm, mainEm);
//Verify the navigations are still working
Assert.AreSame(contact, detail.Contact);
Assert.AreSame(detail, contact.ContactDetail);
//Now do a similar import except we'll import into the dummy EM before importing into the main EM.
// This 'double import' seems to cause the problem. It would also break if we imported twice into
// main EM.
var dummy = new EntityManager();
ImportAll(altEm, dummy, mainEm, mainEm);
//Verify once more. This one will pass ...
Assert.AreSame(contact, detail.Contact);
//...but this will fail. The Contact Detail is in the Entity Manager and it can navigate to its related
// Contact...but for some reason, the Contact can't navigate to the Detail any longer. Instead of
// being the expected Contact Detail entity, it is a Null Entity
Assert.AreSame(detail, contact.ContactDetail);
}
//Perhaps a bit of an odd way to copy entities between entity managers but it seems like this should be a
// reasonable thing to do
private static void ImportAll(EntityManager source, params EntityManager[] destinations)
{
var ecs1 = source.CacheStateManager.GetCacheState();
foreach (var destination in destinations)
{
destination.CacheStateManager.RestoreCacheState(ecs1, RestoreStrategy.Normal);
}
}
我们正在运行Dev Force 2012的最新版本(截至撰写本文时):7.2.3。
答案 0 :(得分:1)
这里的根本问题是DevForce如何与1:1关系中所谓的“未解析的父”实体一起工作的问题。多个导入/变异的EntityCacheState问题主要是一个红色的鲱鱼,但确实暴露了这个问题。
版本7.2.4中已修复此问题。
答案 1 :(得分:0)
我认为我们已经解决了这个问题,但如果可能的话,我们希望为您提供测试版,以确保它能够解决您的应用中的问题。请告诉我,我将为我们的ftp网站压缩包裹。
问题是EntityCacheState实际上会在每次使用时发生变异,这会导致一些奇怪的边缘条件。
在您的测试用例中,您可能会注意到以下任一情况的良好结果:
我知道您的真实应用中的问题与测试用例有些不同,但您可能会稍微调整一下代码作为解决方法,直到7.2.4发布。