在每个函数中使用DataContext

时间:2014-04-29 13:58:23

标签: c# sql datacontext

我有一个处理所有数据库操作的类。我已经读过,最好将多个DataContext实例用于不同的读/写/更新/删除操作,而不是一个存在很长时间的DataContext实例。

这意味着在DB上执行读/写/更新/删除的每个函数都需要执行此操作:

    public int GetSomeID(string name)
    {
        using (XXDataContext context = new XXDataContext(connStr))
        {
            ...
        }
    }

    public int GetAnotherID(string name)
    {
        using (XXDataContext context = new XXDataContext(connStr))
        {
            ...
        }
    }

    public void WriteSomething(string text)
    {
        using (XXDataContext context = new XXDataContext(connStr))
        {
            ...
        }
    }

反对仅在构造函数中使用this()并将上下文作为私有成员变量用于每个函数调用。

通过保持每个函数调用创建一个新的DataContext的功能,是否可以使用()在其他地方移动它,所以不是每个函数都必须包含这一行?

4 个答案:

答案 0 :(得分:6)

您可以使用这样的方法来避免重写using代码:

private static void WithContext(Action<XXDataContext> action)
{
    using(XXDataContext context = new XXDataContext(connStr))
        action(context);
}    
private static T WithContext<T>(Func<XXDataContext, T> function)
{
    using(XXDataContext context = new XXDataContext(connStr))
        return function(context);
}

这允许你写:

public int GetSomeID(string name)
{
    WithContext(context => 
        {
            //TODO use context
        });
}

如果这有助于你。

答案 1 :(得分:0)

很抱歉没有直接回答您的问题:

你看对了。 Context实现了Unit of Work模式,并且应该像这样使用。

但是,当您需要在同一个上下文中执行多个操作时,可能会出现一个有效的情况,并且它会对这样的代码很好:

using(var dal = new MyDalUOW()) {

   dal.Delete(s1);
   dal.Update(s2);
   dal.Get(s3);

   dal.Commit()
}

为了拥有这个,你将创建你的Dal类,它将实现IDisposable并将有方法Commit

public class BaseDal: IDisposable {
   private MyDbContext _context;

   public BaseDal() { _context = new MyDbContext; }

   public void Commit() { _context.SaveChanges(); }
}

并且您的所有方法都将使用_context来执行操作。

所以你仍然会使用你的DAL而不是在DAL本身的代码中使用所有这些。

答案 2 :(得分:0)

如果您在桌面/ Windows应用程序中使用它,拥有单个DataContext是没有问题的,但您必须明智地处理它(根据db技术,例如EF或linq2sql),以防止datacontext缓存数据与数据库同步。而且还有一件事,你必须为每个线程使用单独的datacontext。

我在WEB应用程序(ASP NET)中使用它然后建议使用每个请求创建一个新的datacontext实例(并在完成请求时将其丢弃)。

所以这取决于你的解决方案。

答案 3 :(得分:0)

好的,请考虑以下代码:

using (var fileStream = new FileStream(@"C:\temp\test.txt", FileMode.Open))
{
    var bytes = new byte[fileStream.Length];
    fileStream.Read(bytes, 0, (int)fileStream.Length);

    var text = Encoding.Default.GetString(bytes);

    Console.WriteLine(text);
}

它利用了一个使用IDisposable的类;就像DataContext一样。现在,让我们说我们要摆脱using;我们可以这样做:

Read(fileStream =>
{
    var bytes = new byte[fileStream.Length];
    fileStream.Read(bytes, 0, (int)fileStream.Length);

    var text = Encoding.Default.GetString(bytes);

    Console.WriteLine(text);
}, @"C:\temp\test2.txt");

static void Read(Action<FileStream> action, string path)
{
    using (var fileStream = new FileStream(path, FileMode.Open))
    {
        action(fileStream);
    }
}

在此,您注入要执行的代码,同时确保从方法中删除using语句。此外,您可以保证将使用using语句。该程序的输出符合预期:

Hello, World!
Hello, World; from an injected function!
Press any key to continue . . .