簡體   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