C# 多次缓存恢复/导入后Dev Force导航属性出现问题

C# 多次缓存恢复/导入后Dev Force导航属性出现问题,c#,silverlight,devforce,C#,Silverlight,Devforce,我们在应用程序中遇到了一个非常奇怪的问题,我们实体上的导航属性最终变得“混乱”,因为它认为另一端没有实体,而实际上有实体。导航属性是一对一的导航,我知道我们在过去的一对一属性中还存在其他问题,所以我们可能只是遇到了一个奇怪的边缘案例错误 在尝试以最简单的方式重现问题时,我发现我可以通过连续执行两次entityManager.CacheStateManager.RestoreCacheState(someCacheState)来重现问题。做两次会导致问题,但做一次不会。在我们的应用程序中,我们正在

我们在应用程序中遇到了一个非常奇怪的问题,我们实体上的导航属性最终变得“混乱”,因为它认为另一端没有实体,而实际上有实体。导航属性是一对一的导航,我知道我们在过去的一对一属性中还存在其他问题,所以我们可能只是遇到了一个奇怪的边缘案例错误

在尝试以最简单的方式重现问题时,我发现我可以通过连续执行两次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。

我想我们已经解决了这个问题,但如果可能的话,我们希望向您提供测试版,以确保它解决了您应用程序中的问题。让我知道,我会为我们的ftp站点压缩包

问题是EntityCacheState实际上会随着每次使用而变化,这可能会导致一些奇怪的边缘条件

在您的测试用例中,您可能会注意到以下任一方面的良好结果:

  • 如果在ImportAll中的foreach循环中创建新的ECS
  • 如果按照与mainEm中相同的顺序附加altEm实体

我知道您的真实应用程序中的问题与测试用例有些不同,但在7.2.4发布之前,您可以稍微调整代码作为一种解决方法。

这里的根本问题是DevForce如何在1:1关系中处理它所称的“未解决的父级”实体。多重导入/变异EntityCacheState问题主要是一个转移视线的问题,但确实暴露了问题


这已在7.2.4版中修复。

抱歉,我不记得您使用的是DF 2010还是2012。哎呀,我应该包括这些信息。我已经更新了这个问题,但我们在DF2012-7.2.3上。我无法用AW2000中的员工-销售人员1:1关系来重新解释这一点,也无法看到RestoreCacheState和Importenties的正确行为。问题可能在于如何在模型中定义关系。是否要发布(或发送)联系人详细信息实体的EDMX?另外,您是否设置了CloningFns.CloningMethod?在我们的实际应用程序中,我们使用DCS CloningMethod。但在我的简单复制中,我只是使用默认值。我已经压缩了我的样品溶液(包括EDMX等)-你可以得到它,谢谢你的复制。我还在看这个,还没有答案。我会让你知道的。这个问题很容易在我们真正的应用程序中重现,所以我想测试一个测试版,让你知道它是如何运行的!谢谢你建议的解决办法。这非常有帮助。在我们的ftp站点上,Zip被命名为DF7.2.4.Zip。如果你需要的网址,下午我。我得到了更新,谢谢。它解决了我的简单示例应用程序中的问题,但不幸的是,它没有解决实际应用程序中的问题!:-(我可以尝试进一步重现这个问题,但我不确定我会有多成功。在我们真正的应用程序中,我认为我们不会使用ECS两次……我们从服务器获取ECS作为RPC调用的一部分,并将其还原一次(我想)。还原ECS时是否有其他潜在问题?可能是ECS序列化到客户端后进行还原时出现了问题。我可以试着解决这个问题。我尝试过从RPC方法检索ECS和还原/导入ECS的各种方法,但无法重新设置错误。不幸的是,实体合并(用于还原和导入)和导航属性的代码都非常复杂,因此我无法真正指出任何一个看起来可疑的地方。如果你想从真实应用程序中向我发送相关代码片段,我可以进一步尝试。我可以验证这一点。升级到7.2.4已修复我们的问题。