简体   繁体   English

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

[英]Filter results from Stored Procedure using Linq

I have a query which I cannot do in Linq, as it uses 2 separate databases. 我有一个我在Linq无法做的查询,因为它使用了2个独立的数据库。 Instead, I have written a stored procedure in SQL Server. 相反,我在SQL Server中编写了一个存储过程。

Now I need to manipulate the results. 现在我需要操纵结果。

Here is my stored procedure: 这是我的存储过程:

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

And here is my C# code: 这是我的C#代码:

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

First I want to extract from this result a list of distinct UserIDs. 首先,我想从此结果中提取不同UserID的列表。

Then I want to filter those results on a column called UserID . 然后我想在名为UserID的列上过滤这些结果。

Something like this: 像这样的东西:

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

And this: 和这个:

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

Both these examples here come from a different kind of query, like below, but how do I do it with my stored procedure? 这两个例子都来自不同类型的查询,如下所示,但我如何使用我的存储过程呢?

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();

Finally got it working. 终于搞定了。 here is my final code: 这是我的最终代码:

    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();

I think that you can do it in the same way using the Property ReturnValue of the stored procedure. 我认为您可以使用存储过程的Property ReturnValue以相同的方式执行此操作。

Call the stored procedure like this 像这样调用存储过程

[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));
}

then tou can use it in others functions in this way 那么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();

refer here for documentation 请参考这里的文档

eventTable is an ISingleResult<T> , which is an interface that extends IEnumerable<T> to additionally capture the return value of the stored procedure call. eventTable是一个ISingleResult<T> ,它是一个扩展IEnumerable<T>以进一步捕获存储过程调用的返回值的接口。

Where<T> accepts an IEnumerable<T> (which eventTable is), but returns an IEnumerable<T> . Where<T>接受IEnumerable<T>eventTable为),但返回 IEnumerable<T> Since you can't implicitly downcast from an IEnumerable<T> to an ISingleResult<> ,you can't store the result of where back in eventTable , and the compiler throws an error. 由于无法从IEnumerable<T>隐式向下转换为ISingleResult<> ,因此无法将结果存储在eventTable ,并且编译器会抛出错误。

You have some options: 你有一些选择:

  • make eventList an IEnumerable<HealthAndSafetyResult> , either explicitly or using AsEnumerable() : 使eventList成为IEnumerable<HealthAndSafetyResult> ,显式或使用AsEnumerable()

     var eventTable = OnSiteV3.HealthAndSafety(_EventClass, _EventDateTime) .AsEnumerable(); 
  • store the result of Where in a differently-typed variable: Where的结果存储在一个不同类型的变量中:

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

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

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