如果当前对象为 null,则设置一个 using

setup a using if the current object is null

我正在努力使这段代码的重复性降低一些,我觉得如果对象已经为空,应该有一种初始化 using 语句的方法

public static CMSContent GetContent(string title, ContextDb db = null)
    {
        if (db == null)
        {
            using (db = new ContextDb())
            {
                return db.CMSContents.FirstOrDefault(c => c.Title == title && !c.Archived);
            }
        }
        else
        {
            return db.CMSContents.FirstOrDefault(c => c.Title == title && !c.Archived);
        }

    }

这是因为调用语句可能想要 运行 对 returned 对象的进一步数据库请求,或者可能有多个调用并且提前建立了连接以减少多个连接。

如果 return 语句不能被复制会更好,所以如果 db 为 null 则使用 then do。

查看 using 的文档,您可以通过在 finally 子句中调用 Dispose() 来实现相同的行为。

编辑:关于 Nkosi 的评论 - 我们必须记住 db 最初是否为 null。不确定生成的代码是否真的是一个改进,至少 return 语句不再重复...

public static CMSContent GetContent(string title, ContextDb db = null) {
    var dbWasNull = (db == null);
    try {
        if (dbWasNull) {
            db = new ContextDb();
        }
        return db.CMSContents.FirstOrDefault(c => c.Title == title && !c.Archived);
    }
    finally {
        if (dbWasNull) {
            db.Dispose();
        }
    }
}

我接受了 Georg 的回答,经过编辑,并对其进行了一些修整:

public static CMSContent GetContent(string title, ContextDb db = null)
    {
        var _db = db ?? new ContextDb();

        try
        {
            return _db.CMSContents.FirstOrDefault(c => c.Title == title && !c.Archived);
        }
        finally
        {
            if (db == null) _db.Dispose();
        }
    }

我找了很多地方寻找更好的答案,但找不到。除了也许不这样做并且有一个由单例管理的连接池。但这在这里不切实际,希望这能帮助其他人。

我确实想到了不处理上下文并让 GC 这样做的想法,但我认为如果我这样做的话我晚上睡不着觉。

public static CMSContent GetContent(string title, ContextDb db = null)
{
    return (db ?? new ContextDb()).CMSContents.FirstOrDefault(c => c.Title == title && !c.Archived);
}

是的 - 不要那样做。显然 EF5 可以接受,它会自动关闭连接,但 EF6 不是,如果它是一次性的,你应该处理它。