Sql,如何在单个select中基于两个依赖列选择多个结果?

时间:2014-06-30 20:43:49

标签: c# sql

table_Aguid_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中各自的值,但这可能意味着对数据库进行了多次调用。

我以为我可以将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对吗?

2 个答案:

答案 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加入这两个对象将是最有效的。