如何在一次选择中基于两个依赖的列选择多个结果

本文关键字:选择 依赖 于两个 列选 结果 一次 | 更新日期: 2023-09-27 18:11:04

我有table_A,列guid_Aguid_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的多次调用。

我想我可以改变我的IEnumerableDictionary<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连接两个对象将是最有效的。