none
使用N层体系结构删除数据时引发的异常 RRS feed

  • 问题

  • 这是在使用WCF服务来测试LINQ to SQL在N层体系结构中删除数据时遇到的异常。到目前为止,尚不清楚到底如何使用基于时间戳的方式,或者基于原始值的方式删除数据。但是,我并没有修改对象的任何一个属性,而且这个对象也是从数据库获取的,并非我自己构造出来。如果不是N曾体系结构的话,这样的删除操作时非常容易实现的,包括对并发冲突的处理。
    但是,演习的过程却并非一帆风顺的。我将没有做过任何修改的对象附加到数据上下文之后,然后调用已知对象集合的DeleteOnSubmit()方法将其删除,我认为到这里为止应该是没有什么错误的吧。可是很不幸的是,测试始终不成功,怎么修改都没成功,始终引发如下的异常:
    未处理的异常:  System.ServiceModel.FaultException: 由于内部错误,服务器无法处理
    该请求。有关该错误的详细信息,请打开服务器上的 IncludeExceptionDetailInFaults (
    从 ServiceBehaviorAttribute 或从 <serviceDebug> 配置行为)以便将异常信息发送回客
    户端,或在打开每个 Microsoft .NET Framework 3.0 SDK 文档的跟踪的同时检查服务器跟
    踪日志。

    服务端的代码如下:
    public void DeleteCustomer(Customer DeletedCustomer)
    {
        NorthwindExDataContext db = new NorthwindExDataContext();
        StreamWriter Writer = File.CreateText(@"C:\LINQ\NLayer.log");
        db.Log = Writer;

        try
        {
            db.Customers.Attach(DeletedCustomer, false);
            db.Customers.DeleteOnSubmit(DeletedCustomer);
            db.SubmitChanges();
        }
        finally
        {
            Writer.Close();
        }
    }

    客户端的调用代码如下:
    NorthwindServicesClient Client = new NorthwindServicesClient();
    Customer CustomerObject = Client.RetrieveCustomer("ALFKI");
    Client.DeleteCustomer(CustomerObject);
    Console.Read();

    各位帮忙看看,这是怎么回事呢?
    这个问题不解决,什么基于时间戳的方式,还是基于原始值的方式都没法整了。哎!MSDN在这个问题上所提供的示例代码似乎也过于简单了一些。
    谢谢!

    2010年10月5日 8:08

答案

  • 使用全局的DataContext,并不会造成所有的SubChange()一起执行,不过会造成取数据的时候 出现 已有打开的与此命令相关联的 DataReader,必须首先将它关闭。

    建议所有取数据的时候外面加入using语句 取列表的时候,可以使用toList();

    http://www.cnblogs.com/gsralex/archive/2010/06/18/1760338.html

    2010年10月19日 12:26

全部回复

  • 根据MSDN的说法,在N层体系结构中使用LINQ to SQL删除数据至少有两种办法:基于时间戳的方式、基于原始值的方式。
    到底什么情况下是使用基于时间戳的方式呢?请参看下面一段文字:(摘自MSDN)

    删除操作涉及到开放式并发检查,并且必须首先将要删除的对象附加到新的数据上下文。 在此示例中,Boolean 参数设置为 false,以指示该对象没有时间戳 (RowVersion)。 如果数据库表确实为每个记录生成了时间戳,则并发检查会简单得多(特别是对客户端而言)。 只需传入原始对象或已修改的对象,并将Boolean参数设置为 true。

    它这里所说的Boolean参数我想应该指的是已知对象集合的Attacth方法吧。比如db.Customers.Attach(),如果根据这个参数的注释来看,似乎这个参数的作用并非是用来指示是否使用基于时间戳的方式删除数据,而应该是指示所附加的对象是原始对象,还是被修改过的对象。如果被已被修改的话,则返回true;否则就返回false。

    而且根据我的测试,在所生成的删除SQL命令当中也不管时间戳什么事情呀?这到底怎么回事呢?
    或者说在在N层体系结构中到LINQ to SQL到底如何才能使用基于时间戳的方式删除数据呢?

    谢谢!

    2010年10月5日 7:52
  • Customer CustomerObject = Client.RetrieveCustomer("ALFKI");
    Client.DeleteCustomer(CustomerObject);
    获取Customer对象和删除时最好使用一个DataContext. 这样应该不会报错。

    2010年10月7日 2:28
  • 呵呵,当然了。通常情况下是这样的,但是在分层体系结构中,想要使用一个DataContext是不现实的。有人提过使用全局DataContext的办法,此法不太可行,先不要说性能的问题,如果大家都使用同一个DataContext,不管谁调用SubmitChanges()方法,都会将所修改的数据保存到数据库中的,那还了得?这样数据肯定是要出现大问题的。

    2010年10月7日 2:34
  • 你可以用一个线程静态的DataContext嘛。如果是WEB程序,每用户都是单独线程,不会有什么问题。

    如果是分布式倒要考虑一下如何实例化DataContext的问题。

    2010年10月7日 2:41
  • 转:

    社区对于ADO.NET Entity Framework和LINQ to SQL的最大不满,就是它不支持更改跟踪。但只有在你连接到上下文对象的时候,你才可以修改对象并把它们保存回数据库。就像数据库连接那样应该非常快,一旦该上下文对象超出范围,数据对象实质上就进入只读状态。重新附加它们到新上下文来回写它们的更改,这并不是一个好办法。 微软拒绝解决该难题。他们没有像大多数ORM库那样,在数据对象内部添加更改跟踪,改为更加关注POCO或者“简单初始C#对象”。

      个人感觉Linq适用于一些小型系统,开发效率比较高。复杂一点的系统在技术选型时需慎重。

    2010年10月7日 2:53
  • 各位在开发中,一般大型项目都是用是哪些数据库开发技术呀?
    2010年10月8日 2:23
  • # 未处理的异常:  System.ServiceModel.FaultException: 由于内部错误,服务器无法处理
    该请求。有关该错误的详细信息,请打开服务器上的 IncludeExceptionDetailInFaults (
    从 ServiceBehaviorAttribute 或从 <serviceDebug> 配置行为)以便将异常信息发送回客
    户端,或在打开每个 Microsoft .NET Framework 3.0 SDK 文档的跟踪的同时检查服务器跟
    踪日志。

    报的是WCF异常,你最好把IncludeExceptionDetailInFaults 设为true,这样可以在客户端调用时获得更详细的服务端异常信息。你也可以尝试在服务端打开Wcf trace, 有助于你收集错误信息。

    另外,微软已经提供了一些框架来暴露数据服务,比如 WCF RiaServiceWCF data Service,你可以看看。


    Mog Liang
    2010年10月19日 1:43
  • 使用全局的DataContext,并不会造成所有的SubChange()一起执行,不过会造成取数据的时候 出现 已有打开的与此命令相关联的 DataReader,必须首先将它关闭。

    建议所有取数据的时候外面加入using语句 取列表的时候,可以使用toList();

    http://www.cnblogs.com/gsralex/archive/2010/06/18/1760338.html

    2010年10月19日 12:26