linq2sql:单例或使用,最佳实践

zer*_*kms 7 singleton linq-to-sql

当linq2sql使用(在asp.net mvc应用程序中)时,首选的做法是:为DataContextlike 创建"singleton" :

partial class db
{
    static db _db = new db(global::data.Properties.Settings.Default.nanocrmConnectionString, new AttributeMappingSource());

    public static db GetInstance()
    {
        return _db;
    }
}
Run Code Online (Sandbox Code Playgroud)

或者在需要时检索新实例using:

using (db _db = new db())
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

使用using会给代码带来一些限制.所以我更喜欢使用单身之一.这是一种奇怪的做法吗?

UPD:
解释为什么我使用单身人士:

public class UserGroupRepository
{
    public static IQueryable<Group> RolesFor(string username)
    {
        User user = UserRepository.WithUsername(username);

        return from g in db.GetInstance().Groups
                join ug in db.GetInstance().UsersGroups on g.Id equals ug.GroupId
                where ug.UserId == user.Id
                select g;
    }
}
Run Code Online (Sandbox Code Playgroud)

我有这种方法.由于它返回IQueryable - 我可以继续编写查询而不执行它,所以这里只是懒惰的结果返回.
如果我重写相同的代码using- 我无法返回IQueryable(因为db将被丢弃,IQueryable也会丢失),我会将其更改为List.现在这个方法将返回"巨大的"List,我将从中过滤前一个函数的数据.

我希望我描述得足够详细.

Lor*_*nVS 5

Linq to Sql数据上下文不是线程安全的,只应在单个线程的上下文中使用.使用单例模式不仅违反了标准的linq2sql实践,而且如果您的应用程序遇到任何严重的负载,也会导致严重的问题.

编辑:

为了响应您对using块的限制,请尝试将RolesFor方法实现为扩展方法:

public static IQueryable<Group> GetUserRoles(this Database db, string username)
{
        return from g in db.GetInstance().Groups
                join ug in db.GetInstance().UsersGroups on g.Id equals ug.GroupId
                where ug.UserId == user.Id
                select g;
}
Run Code Online (Sandbox Code Playgroud)

这将允许您从任何地方在使用块内调用您的方法:

using(Database db = createContext())
{
     IQueryable<Group> queryable = db.GetUserRoles("MyUsername");
     // from here on you can query the queryable object
     var groups = (from g in queryable
                   where g.Name == "MyRole"
                   select g).ToList();
}
Run Code Online (Sandbox Code Playgroud)

编辑2

响应您关于为数据上下文的每个实例打开与sql server的另一个连接的注释.创建datacontext不会打开与sql server的连接,但每个实际操作都会.无论您是创建1个还是4个datacontexts,如果您在数据库上执行4个操作,将打开4个sqlconnections.但是,请在.NET中使用SQL Server连接池的头脑,所以每个操作不需要建立一个全新的SqlConnection的,但只有一个现有的连接池中的检索和连接的重新开放