【问题标题】:EF 4 Self Tracking Entities does not work as expectedEF 4 自我跟踪实体无法按预期工作
【发布时间】:2010-01-30 01:14:34
【问题描述】:

我正在使用 EF4 自我跟踪实体(VS2010 Beta 2 CTP 2 加上新的 T4 生成器)。但是当我尝试更新实体信息时,它并没有按预期更新到数据库。

我设置了 2 个服务调用。一个用于返回资源对象的 GetResource(int id)。第二个调用是 SaveResource(Resource res);这是代码。

    public Resource GetResource(int id)
    {
        using (var dc = new MyEntities())
        {
            return dc.Resources.Where(d => d.ResourceId == id).SingleOrDefault();
        }        
    }

    public void SaveResource(Resource res)
    {
        using (var dc = new MyEntities())
        {
            dc.Resources.ApplyChanges(res);
            dc.SaveChanges();
            // Nothing save to database.
        }      
    }

    //Windows Console Client Calls
    var res = service.GetResource(1);
    res.Description = "New Change"; // Not updating...
    service.SaveResource(res); 

    // does not change anything.

在我看来,ChangeTracker.State 总是显示为“未更改”。

这段代码有什么问题吗?

【问题讨论】:

    标签: entity-framework self-tracking-entities


    【解决方案1】:

    这可能是一个很长的镜头......但是:

    我假设您的服务实际上是在另一个层?如果您在同一层进行测试,则会遇到问题。

    自跟踪实体 (STE) 在连接到 ObjectContext 之前不会记录更改,其想法是,如果它们连接到 ObjectContext,它可以为它们记录更改,并且重复执行相同的工作是没有意义的.

    STE 在客户端上使用 WCF 反序列化后开始跟踪,即一旦它们被具体化到没有 ObjectContext 的层。

    如果您查看生成的代码,您应该也可以看到如何手动打开跟踪。

    希望对你有帮助

    亚历克斯

    【讨论】:

    • 服务在同一层,但在不同的层。我的想法是将所有内容写在同一层(不同的层),但如果需要,稍后更改为不同的层。在上面的示例中,ObjectContext 超出了每个服务调用的范围,那么为什么 STE 不跟踪。还是 STE 仅适用于 WCF 场景?在上述场景中,无论是性能还是可扩展性,EF 4 的最佳方法是什么(POCO、STE 或其他)?
    • 跟踪是通过反序列化打开的,所以如果你在同一层,它不会被打开,尽管你的 ObjectContext 超出了范围。
    【解决方案2】:

    您必须在客户端和服务之间与 STE 共享程序集——这是重点。然后在添加服务引用时确保选中“在引用的程序集中重用类型”。

    原因是 STE 包含无法通过“添加服务引用”传输的逻辑,因此您必须共享这些类型才能在客户端也有跟踪逻辑。

    【讨论】:

      【解决方案3】:

      阅读 Daniel Simmons 的以下提示后,STE 开始跟踪。这是完整文章的链接。 http://msdn.microsoft.com/en-us/magazine/ee335715.aspx

      确保在您的客户端上重用自我跟踪实体模板生成的实体代码。如果您使用由 Visual Studio 或其他工具中的添加服务引用生成的代理代码,则一切正常大多数情况下,但您会发现实体实际上并没有跟踪他们在客户端上的更改。

      所以在客户端确保你不使用添加服务引用来获取代理,而是通过以下代码访问服务。

      var svc = new ChannelFactory<IMyService>("BasicHttpBinding_IMyService").CreateChannel();
      var res = svc.GetResource(1);
      

      【讨论】:

        【解决方案4】:

        如果您使用没有 WCF 的 STE,您可能必须手动调用 StartTracking()。

        【讨论】:

          【解决方案5】:

          我遇到了同样的问题并找到了解决方案。

          看来,要让自跟踪实体自动开始跟踪,您需要在添加服务引用之前引用您的 STE 项目。

          通过这种方式,Visual Studio 会生成一些 .datasource 文件来完成最后一招。

          我在这里找到了解决方案: http://blogs.u2u.be/diederik/post/2010/05/18/Self-Tracking-Entities-with-Validation-and-Tracking-State-Change-Notification.aspx

          至于手动启动跟踪,客户端好像没有这些方法。

          希望对你有帮助...

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-08-24
            • 2019-08-26
            • 2018-05-03
            • 1970-01-01
            • 2022-07-06
            • 1970-01-01
            相关资源
            最近更新 更多