using (IDbCommand command = new SqlCommand())
{
IDbDataAdapter adapter = new SqlDataAdapter();
DataSet ds = new DataSet();
adapter.SelectCommand = command;
command.Connection = _dataAccess.Connection;
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "GetProcData";
command.Parameters.Add(new SqlParameter("@ProcID ", procId));
adapter.Fill(ds);
return ds.Tables[0].AsEnumerable();
}
这会返回一个IEnumerable DataRow问题是,由于返回在using语句中,它的属性是否会处理IDBCommand?我知道我可以很容易地重构这个,所以我在使用之外更改了DataSet的范围,但它更像是一个奇迹而不是其他任何东西。
答案 0 :(得分:4)
是的,这将按预期正常工作,IDbCommand
处理得当。编译器会将使用块转换为try-catch-finally
,其中Dispose
块中调用finally
。
答案 1 :(得分:2)
是的,数据库命令将被处理,到目前为止一直很好。
你可以通过IEnumerables获得麻烦。因为从IEnumerable获取项目时可能会生成项,而不是在创建IEnumerable时,这就是它的本质。所以它取决于ds.Tables[0].AsEnumerable()
的实现方式。 可以等待执行命令,直到获得第一个项目。这是在使用块之外的调用代码中。你会收到一个错误,因为命令已被处理掉了。
这可能不是问题,但在使用块返回IEnumerables(或lambda表达式)时应始终考虑:
using (A a = new A())
{
return someItems.Select(x => a.Get(x));
}
访问第一项时,a
已经处理完毕,您收到错误。
答案 2 :(得分:2)
正确处理IDbCommand
。从using语句中返回时,您可以这样做,只要:
在第一种情况下,using语句将处理你想要返回的东西,在第二种情况下,变量将超出范围。
e.g。
//this is fine as result is createsd outside the scope of the block.
bool result = false;
using (SmtpClient mailClient = new SmtpClient())
{
try
{
mailClient.Send(...);
result = true;
}
catch(SmtpException)
{
result = false;
}
finally
{
return result;
}
}
这里,using(){ ... }
声明是我们的朋友。当我们退出块时,我们会放置SmtpClient
,结果条件仍然存在供您使用。
但是,假设我们正在编写一个WinForm应用程序或WPF应用程序,我们在数据上下文中包含一个使用块,然后我们会在控件可以使用它之前上下文消失时创建一个问题。
// this will fail when you bind the customers to a form control!
using (DbContext context = new DBContext())
{
context.Customers.Where(c => c.Name.Contains("Bob")).Load();
return context.Customers.Local;
}
在这里,using(){ ... }
声明会伤害我们。当我们将数据绑定到GridView(或其他此类数据绑定控件)时,我们处理DbContext
这一事实将意味着我们的表单没有任何内容可以绑定,因此它会抛出异常!
HTH
答案 3 :(得分:0)
IDbCommand
对象的范围非常明确:括号{
和}
之间。一旦程序流从那里退出,对象就会被处理掉。