使用Linq过滤存储过程的结果

时间:2015-02-13 14:04:57

标签: c# sql-server linq stored-procedures

我有一个我在Linq无法做的查询,因为它使用了2个独立的数据库。相反,我在SQL Server中编写了一个存储过程。

现在我需要操纵结果。

这是我的存储过程:

ALTER PROCEDURE [dbo].[HealthAndSafety] 
    @EventClass nvarchar(50), 
    @EventDateTime datetime
AS
BEGIN
    SELECT     
       SQLPendingEvent.EventType AS Answer,
       (SELECT Description
        FROM RepairCodes
        WHERE (Code = RepairCodes_1.Code) AND (Type = 'HSQUESTION')
       ) AS HSQuestion, 
       (CASE WHEN RepairCodes_1.Type = 'HSANSWERY' THEN 'Yes' ELSE 'No' END) AS HSAnswer, 
       SQLPendingEvent.EventDateTime AS completionDate,  
       SQLPendingEvent.KeyPropertyID, 
       SVSExtract.dbo.Property.Address1 + '  ' + SVSExtract.dbo.Property.Address2 + '  ' + SVSExtract.dbo.Property.Postcode AS Address, 
       SQLPendingEvent.KeyEntityID AS JobNumber, SQLPendingEvent.KeyUserID
   FROM         
      SQLPendingEvent 
   INNER JOIN
      RepairCodes AS RepairCodes_1 ON SQLPendingEvent.EventType = RepairCodes_1.Description 
   LEFT OUTER JOIN
      SVSExtract.dbo.Property ON SQLPendingEvent.KeyPropertyID = SVSExtract.dbo.Property.KeyProperty
   WHERE     
      (SQLPendingEvent.EventClass = @EventClass) 
      AND (SQLPendingEvent.EventCode = 'EVENT') 
      AND (SQLPendingEvent.EventDateTime > @EventDateTime)
   ORDER BY 
      SQLPendingEvent.KeyUserID

这是我的C#代码:

var eventTable = OnSiteV3.HealthAndSafety(_EventClass, _EventDateTime);

首先,我想从此结果中提取不同UserID的列表。

然后我想在名为UserID的列上过滤这些结果。

这样的事情:

var userList = eventTable.AsEnumerable().Select(row => new
        {
            KeyUserID = (string)row.KeyUserID
        }).Distinct();

而且:

eventTable = eventTable.Where(r => r.KeyUserID == selectedUser);

这两个例子都来自不同类型的查询,如下所示,但我如何使用我的存储过程呢?

var eventTable = (from s in OnSiteV3.SQLPendingEvents
                  join r in OnSiteV3.RepairCodes on s.EventType equals r.KeyRepairCode
                  select new
                          {
                              s.KeyDeviceID,
                              s.UpdateTime,
                              s.EventType,
                              s.EventDateTime,
                              s.EventText,
                              s.KeyUserID,
                              s.EventCode,
                              r.Type
                          }).Where(s => s.EventCode == _eventCode && s.Type == _repairType && s.EventDateTime > _EventDateTime).Distinct();

终于搞定了。这是我的最终代码:

    OnSiteV3DataContext OnSiteV3 = new OnSiteV3DataContext();

            var eventTable = OnSiteV3.HealthAndSafety(_EventClass, _EventDateTime).ToList();

            if (selectedUser != string.Empty)
            {
                var eventTableFiltered = eventTable.Where(o => o.KeyUserID == selectedUser).ToList();
                gvHealthAndSafety.DataSource = eventTableFiltered;
                gvHealthAndSafety.DataBind();
            }
            else
            {
                gvHealthAndSafety.DataSource = eventTable;
                gvHealthAndSafety.DataBind();
            }

            var userList = eventTable.Select(row => new { KeyUserID = (string)row.KeyUserID }).Distinct();

            ddlUsers.DataSource = userList;
            ddlUsers.DataTextField = "KeyUserID";
            ddlUsers.DataValueField = "KeyUserID";
            ddlUsers.DataBind();

2 个答案:

答案 0 :(得分:0)

我认为您可以使用存储过程的Property ReturnValue以相同的方式执行此操作。

像这样调用存储过程

[Function(Name="dbo.Call me as you want")]
public ISingleResult<YourTableResult> GetSomething([Parameter(DbType="NVarChar(20)")] string param1)
{
    IExecuteResult result = this.ExecuteMethodCall(this,         ((MethodInfo)(MethodInfo.GetCurrentMethod())), param1);
    return ((ISingleResult<YourTableResult>)(result.ReturnValue));
}

然后tou可以用这种方式在其他函数中使用它

ISingleResult<YourTableResult> result =
        db.GetSomething("ParameterValue");

//now you can use the code that you already use like this

    var userList = result.AsEnumerable().Select(row => new
            {
                KeyUserID = (string)row.KeyUserID
            }).Distinct();

请参阅here了解文档

答案 1 :(得分:0)

eventTableISingleResult<T>,它是一个扩展IEnumerable<T>以进一步捕获存储过程调用的返回值的接口。

Where<T>接受IEnumerable<T>eventTable是),但返回 IEnumerable<T>。由于您无法从IEnumerable<T>隐式向下转换为ISingleResult<>,因此无法将结果存储在eventTable中,并且编译器会抛出错误。

你有一些选择:

  • 明确或eventList使IEnumerable<HealthAndSafetyResult>成为AsEnumerable()

    var eventTable = OnSiteV3.HealthAndSafety(_EventClass, _EventDateTime)
                             .AsEnumerable();
    
  • Where的结果存储在不同类型的变量中:

    var eventTableFiltered = eventTable.Where(r => r.KeyUserID == selectedUser);