使用多个SQL连接
本文关键字:SQL 连接 | 更新日期: 2023-09-27 18:28:17
我目前正在通过练习面向对象编程来发展我的编码技能。
我正在使用大量的SQL连接来检索初始化类对象的信息。不过,我相信我做得不好,因为我同时初始化了大量的SQL连接。我经常需要同时运行几个连接,以便完成对主类的初始化。下面是我的意思的一个简短例子。
我有好几节课。每个类都有不同类类型的几个属性。下面是一个简单的例子,说明它的主要外观:
public class UserAccount
{
public long UserId { get; set; }
public string UserName { get; set; }
public Address UserAddress { get; set;}
}
public class UserAddress
{
public long AddressId { get; set; }
public string Address { get; set; }
}
现在,为了检索关于这些类中每一个的信息,我正在使用特定的方法从数据库中提取每个类属性的值。以下是我的方法如何查找类UserAccount:
public static UserAccount GetUserAccountById(long id)
{
UserAccount result = null;
using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["connectionString"].ConnectionString))
{
using (SqlCommand cmd = new SqlCommand(string.Empty, con))
{
cmd.CommandText = "SELECT * FROM UserAccounts WHERE UserId = @Id";
cmd.Parameters.AddWithValue("@Id", id);
con.Open();
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (reader.Read())
result = RetrieveFromDatabaseRow(reader);
}
con.Close();
}
}
return result;
}
public static UserAccount RetrieveFromDatabaseRow(SqlDataReader reader)
{
try
{
return new UserAccount
{
UserId = (long)reader["UserId"],
UserName = (string)reader["UserName"],
UserAddress = UserAddress.GetUserAddressById((long)reader["PrimaryAddressId"])
};
}
catch (Exception unhandledException)
{
GlobalMethods.LogException(unhandledException);
return null;
}
}
现在UserAddress.GetUserAddressById方法与我的第一个类的提取方法基本相同。它初始化连接并运行SQL命令。
为什么我认为我做错了:目前的执行方式会导致几个SQL连接同时打开(在我的示例中只有2个,但在我的实际项目中还有更多)。
我想做一个巨大的SQL语句,将所有需要的SQL表连接到一个命令中,然后提取所有这些信息,以便初始化主类,而无需从其属性(例如UserAddress类)请求其他信息。但这对我来说并不好笑,因为我经常需要同时检索很多信息,有时一句话是不够的。此外,编写一个连接十个表的庞大SQL语句是一件令人头疼的事。
我正在考虑创建一个全局SqlConnection变量,该变量将只初始化一次,并且我的所有SQL查询都将同时通过他。不过,我不知道它会对这种行为做出什么反应。
我可以使用一些技巧和提示来正确执行这一操作。提前谢谢。
我想做一个巨大的SQL语句,将所有需要的SQL表连接到一个命令中
可能不是一个好主意,因为你提到的原因——你要求的数据比必要的多得多。此外,每次您的数据模式更改时,您都必须维护该语句
我正在考虑创建一个全局SqlConnection变量,该变量将只初始化一次,并且我的所有SQL查询都将同时通过他。
再说一遍,这不是一个好主意。SQL连接是池化的,因此创建它们通常不太昂贵。此外,"全局"变量可以降低可测试性,并为设计添加不易删除的依赖项。
您的模式对于低级SQL存储库来说非常典型。一般模式是:
- 生成SQL语句
- 创建/打开连接
- 创建SQL命令
- 执行SQL命令
- 将结果转换为数据结构(DataTable/对象集合)
- 返回数据结构
您可以修改代码以启用一些重用,但这大约是您能得到的最低值,因为每个SQL命令都不同,可能需要特殊处理(参数、事务等)
此外,拥有多个专用SQL语句也有一些优点,包括:
- 效率-只要求提供所需的数据
- 隔离-如果更改一个表的模式,则只需更改直接受影响的命令
- 模块化-如果需要,更改一个实体的来源会更简单
根据评论进行编辑
听起来你看到的是两个极端——一端是分别提取每个对象(10个查询),另一端是提取所有对象并仔细选择要保留的数据。可能有时您希望一次提取几个表,这对于SQL语句来说很容易实现,而不需要所有查询都使用一个单一的SQL语句。
例如,一个查询连接UserAccount
和UserAddress
,然后根据结果创建多个对象。这是完全有效的,并且可以使用您正在使用的模式来完成,而不需要一个巨大的查询来提取所有可能的数据。
像EntityFramework这样的ORM一直都在做这类事情,但当它进入实际的数据库连接时,它使用的模式与您正在使用的模式类似——创建连接、创建命令、执行它、合并结果、关闭连接。
您正在做的事情看起来像Linq给您的东西,主要区别在于没有"Live"数据库查询支持的属性,而是一种一次性在内部填充所有属性的方法。
我建议您仔细查看现有的框架,如Linq-to-SQL或Linq-to-Entities(实体框架)