在 SQL table 的联系人列表中查找匹配的联系人
Find matching contacts from contact list in an SQL table
我目前正在为聊天应用程序编写服务器应用程序,该应用程序从用户地址簿接收 phone 联系人列表作为 List<string>
,其中字符串是标准化的 phone 数字.我现在想将它与保存所有注册用户的 SQL 数据库进行比较。
现在我遍历列表中的每个项目并查询
SELECT * FROM Users WHERE Number = @0
并在每次查询时打开一个与 SqlConnection(connectionString)
的新连接。我这样做是因为我知道 .NET 将 handle/pool 打开连接。
var phoneNumbers = new List<string> { "0049123456789", "001123456789" };
var registeredUsers = new List<string>();
foreach (var phoneNumber in phoneNumbers)
{
try
{
var userName = GetFrom(phoneNumber);
registeredUsers.Add(userName);
}catch{}
}
//...
public static string GetFrom(string telephoneNumber)
{
string retVal = null;
using (var connection = new SqlConnection(connectionString))
{
using (var cmd = SetSQLCommand(connection, "SELECT * FROM Users WHERE Number = @0", telephoneNumber))
{
connection.Open();
using (var reader = cmd.ExecuteReader())
{
if (reader.HasRows)
{
while (reader.Read())//Get last
{
retVal = (string)reader["Name"];
}
}
else
{
throw (new KeyNotFoundException());
}
}
}
}
return retVal;
}
这种方法感觉很愚蠢,因为用户联系人列表可能包含 1000 个或更多联系人。
是否有更优雅的方法从我作为 C# 对象在 SQL table?
由于性能对我来说非常重要,所以我使用 SQL System.Data.SqlClient
的 .NET 4.5 实现,Entity Framework
对我来说太慢了。
当我遇到类似的情况时,这是我的看法:
- 我会将所有 phone 数字连接成一个单一格式的字符串
- 我将利用 "IN" T-SQL
在动态 SQL 查询中传递该字符串
可以这么简单:
public List<string> ReturnContactNames(string telephoneNumbers)
{
var retVal = new List<string>();
using (var connection = new SqlConnection(connectionString))
{
using (var cmd = new SqlCommand("SELECT * FROM Customers WHERE Phone IN (" + telephoneNumbers + ")", connection))
{
connection.Open();
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
retVal.Add((string)reader["ContactName"]);
}
}
}
}
return retVal;
}
然后这就是您可以使用此方法的方式:
var phoneNumbers = "'030-0074321','0621-08460'";
var list = ReturnContactNames(phoneNumbers);
警告:尽可能使用参数化查询。这只是一个快速示例,仅供您参考。
希望对您有所帮助。
我目前正在为聊天应用程序编写服务器应用程序,该应用程序从用户地址簿接收 phone 联系人列表作为 List<string>
,其中字符串是标准化的 phone 数字.我现在想将它与保存所有注册用户的 SQL 数据库进行比较。
现在我遍历列表中的每个项目并查询
SELECT * FROM Users WHERE Number = @0
并在每次查询时打开一个与 SqlConnection(connectionString)
的新连接。我这样做是因为我知道 .NET 将 handle/pool 打开连接。
var phoneNumbers = new List<string> { "0049123456789", "001123456789" };
var registeredUsers = new List<string>();
foreach (var phoneNumber in phoneNumbers)
{
try
{
var userName = GetFrom(phoneNumber);
registeredUsers.Add(userName);
}catch{}
}
//...
public static string GetFrom(string telephoneNumber)
{
string retVal = null;
using (var connection = new SqlConnection(connectionString))
{
using (var cmd = SetSQLCommand(connection, "SELECT * FROM Users WHERE Number = @0", telephoneNumber))
{
connection.Open();
using (var reader = cmd.ExecuteReader())
{
if (reader.HasRows)
{
while (reader.Read())//Get last
{
retVal = (string)reader["Name"];
}
}
else
{
throw (new KeyNotFoundException());
}
}
}
}
return retVal;
}
这种方法感觉很愚蠢,因为用户联系人列表可能包含 1000 个或更多联系人。
是否有更优雅的方法从我作为 C# 对象在 SQL table?
由于性能对我来说非常重要,所以我使用 SQL System.Data.SqlClient
的 .NET 4.5 实现,Entity Framework
对我来说太慢了。
当我遇到类似的情况时,这是我的看法:
- 我会将所有 phone 数字连接成一个单一格式的字符串
- 我将利用 "IN" T-SQL 在动态 SQL 查询中传递该字符串
可以这么简单:
public List<string> ReturnContactNames(string telephoneNumbers)
{
var retVal = new List<string>();
using (var connection = new SqlConnection(connectionString))
{
using (var cmd = new SqlCommand("SELECT * FROM Customers WHERE Phone IN (" + telephoneNumbers + ")", connection))
{
connection.Open();
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
retVal.Add((string)reader["ContactName"]);
}
}
}
}
return retVal;
}
然后这就是您可以使用此方法的方式:
var phoneNumbers = "'030-0074321','0621-08460'";
var list = ReturnContactNames(phoneNumbers);
警告:尽可能使用参数化查询。这只是一个快速示例,仅供您参考。
希望对您有所帮助。