在LINQ-SQL中,包装DataContext是一个using语句-优缺点
在性能、内存使用、编码的易用性、正确的操作等因素方面,有人能就在using语句中包装DataContext与不在LINQ-SQL中包装DataContext的利弊发表自己的看法吗 更新:在一个特定的应用程序中,我体验到,在不使用块包装DataContext的情况下,内存使用量会不断增加,因为没有为GC释放活动对象。在下面的示例中,如果我持有对q对象列表的引用和对q的访问实体的引用,我将创建一个不为GC发布的对象图在LINQ-SQL中,包装DataContext是一个using语句-优缺点,linq,linq-to-sql,datacontext,using,Linq,Linq To Sql,Datacontext,Using,在性能、内存使用、编码的易用性、正确的操作等因素方面,有人能就在using语句中包装DataContext与不在LINQ-SQL中包装DataContext的利弊发表自己的看法吗 更新:在一个特定的应用程序中,我体验到,在不使用块包装DataContext的情况下,内存使用量会不断增加,因为没有为GC释放活动对象。在下面的示例中,如果我持有对q对象列表的引用和对q的访问实体的引用,我将创建一个不为GC发布的对象图 DBDataContext db = new DBDataContext() va
DBDataContext db = new DBDataContext()
var qs =
from x in db.Tables
where x.Id == someId
select x;
return qs.toList();
foreach(q in qs)
{
process(q);
// cannot dispose datacontext here as the 2nd iteration
// will throw datacontext already disposed exception
// while accessing the entity of q in process() function
//db.Dispose();
}
process(Table q)
{
// access entity of q which uses deferred execution
// if datacontext is already disposed, then datacontext
// already disposed exception is thrown
}
DataContext与使用
using (DBDataContext db = new DBDataContext())
{
var q =
from x in db.Tables
where x.Id == someId
select x;
return q.toList();
}
DataContext不使用并保持活动状态
DBDataContext db = new DBDataContext()
var q =
from x in db.Tables
where x.Id == someId
select x;
return q.toList();
谢谢 与其他事物相比,创建DataContext的成本可能会很高。但是,如果您已经完成了,并且希望尽快关闭连接,那么也可以从上下文中释放任何缓存的结果。记住,不管发生什么,你都在创建它,在这种情况下,你只是让垃圾收集器知道还有更多的免费东西要处理 DataContext被设计成一个简短的使用对象,使用它,完成工作单元,走出去……这正是你使用一个使用对象所做的 因此,优势在于:
- 快速闭合连接
- 从dispose释放内存(内容中的缓存对象)
请看下面的Microsoft答案:
如果您需要使用使用/.Dispose()
:
简短的回答;不,你不必,但你应该
嗯,这是一个IDisposable
,所以我想这不是个坏主意。MSFT的同事们说,他们使DataContext尽可能轻量级,以便您可以不计后果地创建它们,因此您可能不会获得太多的收益….I取决于数据层的复杂性。如果每个调用都是一个简单的查询,那么每个调用都可以像在您的问题中一样包装在Using中,这样就可以了
另一方面,如果您的数据层可以预期来自业务层的多个连续调用,那么您将为每个较大的调用序列重复创建/处理DataContext。不理想
我所做的是尽可能创建我的数据层对象。创建DataContext时,会创建DataContext(或者说,一旦对方法进行了第一次调用),当数据层对象被释放时,它会关闭并释放DataContext
下面是它的样子:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
namespace PersonnelDL
{
public class PersonnelData : IDisposable
{
#region DataContext management
/// <summary>
/// Create common datacontext for all data routines to the DB
/// </summary>
private PersonnelDBDataContext _data = null;
private PersonnelDBDataContext Data
{
get
{
if (_data == null)
{
_data = new PersonnelDBDataContext(ConfigurationManager.ConnectionStrings["PersonnelDB"].ToString());
_data.DeferredLoadingEnabled = false; // no lazy loading
//var dlo = new DataLoadOptions(); // dataload options go here
}
return _data;
}
}
/// <summary>
/// close out data context
/// </summary>
public void Dispose()
{
if (_data != null)
_data.Dispose();
}
#endregion
#region DL methods
public Person GetPersonByID(string userid)
{
return Data.Persons.FirstOrDefault(p => p.UserID.ToUpper().Equals(userid.ToUpper()));
}
public List<Person> GetPersonsByIDlist(List<string> useridlist)
{
var ulist = useridlist.Select(u => u.ToUpper().Trim()).ToList();
return Data.Persons.Where(p => ulist.Contains(p.UserID.ToUpper())).ToList();
}
// more methods...
#endregion
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用系统配置;
命名空间人员
{
公共类人员数据:IDisposable
{
#区域数据上下文管理
///
///为数据库的所有数据例程创建公共datacontext
///
private PersonnelDBDataContext_data=null;
私人人员数据上下文数据
{
得到
{
如果(_data==null)
{
_数据=新的PersonnelDBDataContext(ConfigurationManager.ConnectionString[“PersonnelDB”].ToString());
_data.DeferredLoadingEnabled=false;//无延迟加载
//var dlo=new DataLoadOptions();//数据加载选项位于此处
}
返回数据;
}
}
///
///关闭数据上下文
///
公共空间处置()
{
如果(_data!=null)
_data.Dispose();
}
#端区
#区域DL方法
公共人物GetPersonByID(字符串用户ID)
{
返回Data.Persons.FirstOrDefault(p=>p.UserID.ToUpper().Equals(UserID.ToUpper());
}
公共列表GetPersonsByIDlist(列表用户IDList)
{
var ulist=useridlist.Select(u=>u.ToUpper().Trim()).ToList();
返回Data.Persons.Where(p=>ulist.Contains(p.UserID.ToUpper()).ToList();
}
//更多方法。。。
#端区
}
}
在一个特定的应用程序中,我体验到,如果不将DataContext
包装在using
块中,内存使用量会不断增加,因为没有为GC释放活动对象。在下面的示例中,如果我持有对List
对象的引用并访问q
的实体,我将创建一个不为GC发布的对象图
DBDataContext db = new DBDataContext()
var qs =
from x in db.Tables
where x.Id == someId
select x;
return qs.toList();
foreach(q in qs)
{
process(q);
// cannot dispose datacontext here as the 2nd iteration
// will throw datacontext already disposed exception
// while accessing the entity of q in process() function
//db.Dispose();
}
process(Table q)
{
// access entity of q which uses deferred execution
// if datacontext is already disposed, then datacontext
// already disposed exception is thrown
}
在这个示例中,我无法处理datacontext,因为列表变量qs
**中的所有表
实例都共享相同的datacontext。在Dispose()
之后,访问进程(表q)
中的实体会抛出一个datacontext已处理的异常
对我来说,丑陋的kluge是在foreach循环之后删除q对象的所有实体引用。当然,更好的方法是使用using
语句
根据我的经验,我会说使用using
语句
第一次DataContext将从DB获取对象李>
下次启动查询以获取相同的对象(相同的参数):您将在探查器中看到查询,但DataContext中的对象不会被DB中的新对象替换李>
更不用说,在每个DataContext后面都有您从DB请求的所有对象的标识映射(您不想保留这个)
DataContext的整个概念是工作单元,具有乐观并发性。
用于短期交易(仅一次提交)和处置
不要忘记dispose的最好方法是使用()。显然,我们听到过关于创建DataContext的复杂性的不同说法。@James-虽然它没有那么重,但相对于其他东西来说,在我的c