繁体   English   中英

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

[英]Filter results from Stored Procedure using Linq

我有一个我在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();

我认为您可以使用存储过程的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();

请参考这里的文档

eventTable是一个ISingleResult<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); 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM