C# 字段成员与方法变量?

C# 字段成员与方法变量?,c#,asp.net,class,C#,Asp.net,Class,最近我一直在思考类字段成员和方法变量之间的性能差异。我的确切意思如下例所示: 假设我们有一个DataContext对象用于Linq2SQL class DataLayer { ProductDataContext context = new ProductDataContext(); public IQueryable<Product> GetData() { return context.Where(t=>t.ProductId ==

最近我一直在思考类字段成员和方法变量之间的性能差异。我的确切意思如下例所示:

假设我们有一个
DataContext
对象用于Linq2SQL

class DataLayer
{
    ProductDataContext context = new ProductDataContext();

    public IQueryable<Product> GetData()
    {
       return context.Where(t=>t.ProductId == 2);
    }
}
(*1)所以我们知道的第一件事是,如果我们将
ProductDataContext
实例定义为一个字段,我们可以在类中的任何地方找到它,这意味着我们不必一直创建同一个对象实例

但假设我们谈论的是Asp.NET,一旦用户按下“提交”按钮,post数据将发送到服务器,事件将被执行,发布的数据通过上述方法存储在数据库中,因此,很可能同一用户可以一个接一个地发送不同的数据。如果我在页面执行后正确知道,终结器开始工作并从内存(从堆)中清除内容,这意味着我们也会从内存中丢失实例变量,在另一篇文章之后,应该为新的页面周期再次创建
DataContext

因此,向全班公开声明它的唯一好处似乎就是上面的第一条文本

还是有别的什么

先谢谢你


(如果我说了不正确的话,请纠正我…)

您永远不想在类级别存储。如果您这样做了,那么您将不得不在类上实现该方法,并在您知道已完成该方法时调用该方法

最好在方法中创建一个新的DataContext,并在完成后使用自动处理

尽管IDisposable在DataContext上的实现没有任何作用,但这是一个实现细节,而公开IDisposable接口是一个您应该始终遵守的契约

如果您升级到LINQtoEntities并在处理完实例后在实例上使用where-you-must-call-Dispose,这将非常方便,否则,资源将泄漏到下一次垃圾收集

因此,这似乎是唯一的好处 向全体公开宣布 类是唯一排名第一的文本 上面

是的,声明类级别变量是为了允许整个类访问同一个变量。不应使用它来尝试并故意防止垃圾收集的发生。属性、方法等上的访问修饰符用于确定类的外部或内部对象可以使用该代码段访问/修改/monkey


在ASP.NET中,一旦请求被发送到浏览器,为该页面请求创建的对象将在将来某个时间点得到CGE,而不管该变量是否为公共变量。如果希望在请求之间保留信息,则需要创建对象的单例实例,或者将对象序列化为会话或应用程序状态

对于每个方法或每个类实例创建对象的性能差异,我不太担心。然而,这里您似乎忽略了DataContext类和工作单元模式的一些重要原则

DataContext类作为单个工作单元运行。因此,您可以创建DataContext,创建对象,更新和删除对象,提交所有更改,然后处理DataContext。您可以为每个请求创建多个DataContext类,为每个(业务)事务创建一个。但是在ASP.NET中,您永远不应该创建一个能够在web请求中生存的DataContext。在请求期间创建的所有DataContext都应该在该请求结束时或之前进行处理。这有两个原因

首先,DataContext具有从数据库中获取的所有对象的内部缓存。长时间使用DataContext会使其缓存无限增长,并且在拥有大型数据库时会导致内存问题。DataContext还支持在可能的情况下从缓存返回对象,使对象很快过时。由于这种陈旧性,对另一个DataContext或直接对数据库执行的任何更新和删除操作都可能被忽略

不缓存数据上下文的第二个原因是它们不是线程安全的。最好将DataContext视为工作单元或(业务)事务。创建一组新对象,将它们添加到DataContext,更改其他一些对象,删除一些对象,完成后,调用SubmitChanges。如果在该操作期间,另一个请求在同一实例上调用SubmitChanges,则您将无法理解该事务。当您允许代码执行此操作时,在最幸运的情况下,您的新对象将被持久化,并且您的事务将分为两个单独的事务。最糟糕的情况是,您将DataContext或它所保存的对象保持在无效状态,这可能意味着其他请求失败或无效数据进入数据库。这并不是不可能发生的情况,我看到过一些奇怪的事情发生在项目中,开发人员为每个网站创建了一个(静态)DataContext

记住这一点,让我们回到你的问题上来。虽然将DataContext定义为实例字段不是问题,但了解如何使用
DataLayer
类很重要。当您为每个请求或每个方法调用创建一个
DataLayer
时,您可能是安全的,但在这种情况下,您不应该将该
DataLayer
存储在静态字段中。当您想要这样做时,应该为每个方法调用创建一个DataContext

了解
数据层
类的设计很重要。在代码中,您只向我们显示一个查询方法。没有反刍的方法。是每个方法都是一个事务,还是要调用多个方法,然后在
数据层上调用SaveChanges
?当您需要最后一个选项时,您需要存储
class DataLayer
{
    public IQueryable<Product> GetData()
    {
       ProductDataContext context = new ProductDataContext();
       return context.Where(t=>t.ProductId == 2);
    }
}