如何在一次选择中基于两个依赖的列选择多个结果
本文关键字:选择 依赖 于两个 列选 结果 一次 | 更新日期: 2023-09-27 18:11:04
我有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
的各自值,但这可能意味着对DB的多次调用。
我想我可以改变我的IEnumerable
为Dictionary<Guid, IEnumerable<Guid>> where the key Guid is guid_A and the value is an
IEnumerable '与guid_A一起出现的所有guid_B,而不是使用一个选择。
SELECT guid_A, guid_B
FROM table_A
WHERE guid_A = @guidA AND guid_B in (...a list of guids...)
,因为我在Dictionary
上迭代,构建了guids列表。这样,我只需要在Dictionary
键中对每个guid_A进行一次调用。但我希望可能有一个更好的方法来解决这个问题,这将帮助我选择所有现有的对guid_A, guid_B从一个单一的select查询列表?
听起来您正在寻找的是一个接受表值参数的存储过程。
为此,首先需要在数据库中创建一个类型,用作存储过程参数的类型:
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();
}
内存列表和数据库表的相对大小是多少?
如果内存中的列表很大,而DB表较小,则可能将整个表加载到内存中,然后使用LINQ连接两个对象将是最有效的。