我table_A
列guid_A
和guid_B
,表格中包含主键(guid_A, guid_B)
。我想在我的应用程序中选择IEnumerable<Tuple<Guid, Guid>>
中存在的所有guid对,但我不确定如何最有效地执行此操作。最天真的我可以反复打电话:
SELECT guid_A, guid_B
FROM table_A
WHERE guid_A = @guidA AND guid_B = @guidB
当我迭代IEnumerable<Tuple<Guid, Guid>>
时,将参数设置为Tuple
中各自的值,但这可能意味着对数据库进行了多次调用。
我以为我可以将IEnumerable
更改为与guid_A一起出现的所有guid_B的Dictionary<Guid, IEnumerable<Guid>> where the key Guid is guid_A and the value is an
IEnumerable`,而是使用类似的选择。
SELECT guid_A, guid_B
FROM table_A
WHERE guid_A = @guidA AND guid_B in (...a list of guids...)
当我继续遍历Dictionary
构建guid列表时。这样我只需要在我的Dictionary
密钥中按guid_A进行一次调用。但我曾希望有更好的方法可以帮助我从一个SELECT查询中的列表中选择所有现有的guid_A,guid_B对吗?
答案 0 :(得分:1)
听起来你正在寻找的是一个接受Table-Valued Parameter的存储过程。
为此,首先需要在数据库中创建一个类型,以用作存储过程参数的类型:
CREATE TYPE TVP_Guids AS TABLE(
GUID_A UNIQUEIDENTIFIER NOT NULL ,
GUID_B UNIQUEIDENTIFIER NOT NULL
)
GO
然后,您需要使用类型和表创建过程:
CREATE PROCEDURE s_Get_GUIDs
@TVPGuids TVP_Guids READONLY
AS
SELECT *
FROM table_A t INNER JOIN @TVPGuids g
ON t.GUID_A = g.GUID_A
AND t.GUID_B = t.GUID_B
GO
最后,您需要在代码中填充参数:
// Placeholder for the real collection
IEnumerable<Tuple<Guid, Guid>> cGUIDs;
// create a data table that will be used to hold your GUIDs
var oTable = new DataTable("GUIDs");
oTable.Columns.Add("GUID_A", typeof(Guid));
oTable.Columns.Add("GUID_B", typeof(Guid));
// Add each of the guids from ienumerable to the datatable
foreach (var oTuple in cGUIDs)
{
oTable.Rows.Add(oTuple.Item1, oTuple.Item2);
}
using (var oConnection = new SqlConnection("Server=localhost;Database=YourDatabase;Trusted_Connection=True;"))
{
oConnection.Open();
using (var oCommand = new SqlCommand("s_Get_GUIDs", oConnection))
{
oCommand.CommandType = CommandType.StoredProcedure;
var oParameter = oCommand.Parameters.AddWithValue("@TVPGuids", oTable);
// This is necessary so ado.net knows we are passing a table-valued parameter
oParameter.SqlDbType = SqlDbType.Structured;
oCommand.ExecuteReader();
// ToDo: Add remaining code here
}
oConnection.Close();
}
答案 1 :(得分:0)
内存列表和数据库表的相对大小是多少?
如果内存列表很大且DB表较小,则可能将整个表加载到内存中,然后使用LINQ加入这两个对象将是最有效的。