简体   繁体   English

使用Linq-to-SQL从存储过程中检索多个数据

[英]Retrieve multiple data from stored procedure using Linq-to-SQL

I am using Silverlight and Linq-to-SQL to communicate with the database. 我正在使用Silverlight和Linq-to-SQL与数据库进行通信。

I have a stored procedure which receives 2 parameters ( PFOID and Quantity ) and Userid and returns a product name. 我有一个存储过程,它接收2个参数( PFOIDQuantity )和Userid并返回一个产品名称。

If we send multiple values like multiple pfoid 's and quantity 's it will return multiple product names shown as below 如果我们发送多个值(如多个pfoidquantity ),它将返回多个产品名称,如下所示

The stored procedure looks like this.. 存储过程如下所示。

ALTER PROCEDURE [PFO].[PFOValidateUpdateData]
    @PfoIDs xml, -- list of PFO ID's
    @UserID uniqueidentifier --The Identity of the User making the call.
AS
BEGIN
    -- SET DEFAULT BEHAVIOR
    SET NOCOUNT ON          -- Performance: stops rows affected messages
    SET DEADLOCK_PRIORITY LOW   -- This SP to be the Deadlock victim

    -- Initialise Lock-Timeout and Deadlock vars for Insert
    DECLARE @iLockTimeoutRetries as int 
    DECLARE @iDeadLockRetries as int
    DECLARE @dtLockTimeoutSleepInterval as datetime 
    DECLARE @dtDeadlockSleepInterval as datetime
    DECLARE @iErrorNumber as int

    SET @iLockTimeoutRetries = 0 
    SET @iDeadLockRetries = 0 
    SET @dtLockTimeoutSleepInterval = sCommon.fnLockTimeoutSleepInterval()
    SET @dtDeadlockSleepInterval= sCommon.fnDeadlockSleepInterval()
    SET @iErrorNumber = 0

    -- procedure specific
    DECLARE @idoc as int
    DECLARE @IsBrightstarUser as bit

    RETRY:
    BEGIN TRY
        --Create Temp table to store stores!
        CREATE TABLE [#PFOList]
        (
            [PFOId] nvarchar(50),
            [Quantity] INT
        )

        --Create Temp table to store User stores!
        CREATE TABLE [#UserStoreList]
        (
            [StoreID_XRef]      nvarchar(50)
        )

       print CONVERT(varchar(1000), @PfoIDs)

        --Create Document
        EXEC sp_xml_preparedocument @idoc OUTPUT, @PfoIDs

        -- Append to new list of Store records
        INSERT INTO [#PFOList] (
                    [PFOId],
                    [Quantity]
                    )
        SELECT  [PFOID],[Quantity]
        FROM OPENXML (@idoc, 'ArrayOfString/string',2)
        WITH( [PFOID] nvarchar(50),[Quantity] [INT]) Stores
        --WHERE [PFOId] Is Not NULL

        -- Clean UP
        exec sp_xml_removedocument @iDoc

        -- are we dealing with a brightstar user?
        SET @IsBrightstarUser = CASE WHEN exists
            (SELECT *
            FROM dbo.aspnet_UsersInRoles AS uir inner join
            dbo.aspnet_Roles  AS roles ON uir.RoleId = roles.roleid
            WHERE roles.rolename = 'Brightstar Employee' and uir.userid = @userid)
            THEN 1 ELSE 0 END

         --Get User Storelist
         INSERT INTO [#UserStoreList] (
                    [StoreID_XRef]
                    )
         SELECT s.StoreId_XRef  
         FROM  PFO.UserStoreLink us(nolock)
         INNER JOIN PFO.Store  s(nolock)
         ON us.StoreId=s.StoreId
         where UserId=@UserID        

         --Select * from [#PFOList]
         --SELECT @IsBrightstarUser AS ISBrightstaruser
         --SELECT * from [#UserStoreList]

    --If BrightstarCustomer Update all the Quantities.
    IF @IsBrightstarUser=1
    BEGIN
               UPDATE 
                    PFO.PFO
                SET
                     IsBrightstarReviewComplete = 1
                    ,[ModifyingUsersID] = @UserID
                    ,[ModifiedDate] = getdate()
                    ,[PlannedQty] = pfol.[Quantity]
                    ,[BrightstarReviewedQty]=pfol.[Quantity]
                FROM
                    PFO.PFO as pfo
                    INNER JOIN [#UserStoreList] as stores on pfo.StoreId_XRef=stores.StoreID_XRef           
                    INNER JOIN [#PFOList] as pfol on pfo.PFOId =  pfol.PFOId 
                WHERE @IsBrightstarUser = 1     
    END
    ELSE BEGIN    
           --Update Non Contrained Orders
           UPDATE 
                PFO.PFO
            SET
                 [ModifyingUsersID] = @UserID
                ,[ModifiedDate] = getdate()
                ,[PlannedQty] = pfol.[Quantity]
            FROM
                PFO.PFO (nolock) as pfo
                INNER JOIN [#UserStoreList] as stores on pfo.StoreId_XRef=stores.StoreID_XRef           
                INNER JOIN [#PFOList] as pfol on pfo.PFOId =  pfol.PFOId 
            WHERE pfo.IsBrightstarReviewComplete=1  AND IsConstraint=0

           --SELECT * from PFO.PFO (nolock) where PFOId='04676723-2afb-49ff-9fa1-0131cabb407c'

        --Update Contrained Orders
        --Get Existing quantities for the User
            CREATE TABLE #ExistingProductQuantity
            (
              [PfoID]  nvarchar(100)  
             ,[Product]  nvarchar(255) 
             ,[PlannedQty]  INT 
             ,[BrightstarReviewedQty]  INT    
            )

            CREATE TABLE #CustProductQuantity
            (
              [Product]  nvarchar(255)
             ,[IsUpdatable]  BIT    
            )

            INSERT INTO #ExistingProductQuantity
            ( [PfoID],[Product],[PlannedQty],[BrightstarReviewedQty])
            SELECT PFOId,InventoryId,PlannedQty,BrightstarReviewedQty
            FROM PFO.PFO as pfo
            INNER JOIN [#UserStoreList] as stores on pfo.StoreId_XRef=stores.StoreID_XRef   
            WHERE pfo.IsBrightstarReviewComplete=1 AND IsConstraint=1       

            UPDATE 
            #ExistingProductQuantity
            SET [PlannedQty]=pfol.[Quantity]
            FROM #ExistingProductQuantity eoq
            INNER JOIN [#PFOList] as pfol on eoq.PFOId =  pfol.PFOId 

            INSERT INTO #CustProductQuantity
            (  [Product],[IsUpdatable] )
            SELECT 
            [Product],
            CASE WHEN SUM(PlannedQty)<=SUM(BrightstarReviewedQty) THEN 1 ELSE 0 END
            FROM #ExistingProductQuantity
            GROUP BY [Product]

            --SELECT * from #ExistingProductQuantity
            --SELECT * from #CustProductQuantity

           --Update the products that can be updatable
            UPDATE 
                PFO.PFO
            SET
                 [ModifyingUsersID] = @UserID
                ,[ModifiedDate] = getdate()
                ,[PlannedQty] = pfol.[Quantity]
            FROM
                PFO.PFO as pfo
                INNER JOIN #UserStoreList as stores on pfo.StoreId_XRef=stores.StoreID_XRef         
                INNER JOIN #PFOList as pfol on pfo.PFOId =  pfol.PFOId 
                INNER JOIN #CustProductQuantity as pr on pr.Product=pfo.InventoryId 
            WHERE pfo.IsBrightstarReviewComplete=1 AND pr.IsUpdatable=1 AND IsConstraint=1

           --Return the products that are not updatabele    
             select  [Product]          
             FROM #CustProductQuantity
             where [IsUpdatable]=0
    END 
    END TRY
    BEGIN CATCH
        -- Get the ErrorNumber
        Set @iErrorNumber = ERROR_NUMBER()

        --Handle Deadlock situation (Deletes, Inserts & Updates)
        IF @iErrorNumber = 1205  
        BEGIN
            -- If we have not made enough attempts to break the lock
            IF @iDeadLockRetries < sCommon.fnMaxDeadlockRetries()
            BEGIN
                -- Increment the Attempt count
                SET @iDeadLockRetries = @iDeadLockRetries + 1
                -- Pause to allow the deadlock contention to clear
                WAITFOR DELAY @dtDeadlockSleepInterval
                GOTO RETRY
            END
        END

        -- Handle Lock Timeout situation (Deletes, Inserts & Updates)
        IF @iErrorNumber = 1222  
        BEGIN       
            -- If we have not made enough attempts to break the Deadlock
            IF @iLockTimeoutRetries < sCommon.fnMaxLockTimeoutRetries()
            BEGIN
                -- Increment the Attempt count
                SET @iLockTimeoutRetries = @iLockTimeoutRetries + 1
                -- Pause to allow the lock contention to clear
                WAITFOR DELAY @dtLockTimeoutSleepInterval
                GOTO RETRY
            END
        END

        exec Common.RethrowError 
    END CATCH
END

The result is as follows.. 结果如下。

 Product
 6435LVWK-360-CD819E3
 NSCHI535C1097I360-4C 
 NSCHU485C1819I360-0C

 Return Value
 0

My Linq-to-SQL connection is like this 我的Linq-to-SQL连接是这样的

[global::System.Data.Linq.Mapping.FunctionAttribute(Name="PFO.PFOValidateUpdateData")]
    public int PFOValidateUpdateData([global::System.Data.Linq.Mapping.ParameterAttribute(Name = "PfoIDs", DbType = "Xml")] System.Xml.Linq.XElement pfoIDs, [global::System.Data.Linq.Mapping.ParameterAttribute(Name = "UserID", DbType = "UniqueIdentifier")] System.Nullable<System.Guid> userID)
    {
        IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), pfoIDs, userID);
        return ((int)(result.ReturnValue));
    }

I am trying to retrieve all the data from the stored procedure but the when I debugging it the return value is "o".. 我正在尝试从存储过程中检索所有数据,但是当我调试它时,返回值是“ o”。

I would be grateful to you if you could help me retrieve all the data returned by the stored procedure... thank you very much... 如果您能帮助我检索存储过程返回的所有数据,我将不胜感激。非常感谢。

If your stored procedure returns a collection of nvarchar's, then the signature of your Linq2Sql method is not correct. 如果您的存储过程返回nvarchar的集合,则Linq2Sql方法的签名不正确。 It should not return an int, but an ISingleResult . 它不应返回int,而应返回ISingleResult

So the correct signature will be: 因此正确的签名将是:

public ISingleResult<string> PFOValidateUpdateData(...)
{
    IExecuteResult result = this....;
    return (ISingleResult<string>)result.ReturnValue;
}

var products = PFOValidateUpdateData(...).ToList();

If you want to return the results from multiple SELECT's in your stored procedure, you'll have to use IMultipleResults . 如果要从存储过程中的多个SELECT返回结果,则必须使用IMul​​tipleResults

Well I know this is not the right way...for time being,its working for me... I created an other table with two columns one ProductId and ID, I am inserting the values returned by the stored procedure, in the designer.cs I am returning the table, 好吧,我知道这不是正确的方法...暂时来说,它对我有用...我创建了另一个带有两列的表,一个是ProductId和ID,我正在将存储过程返回的值插入设计器中.cs我要返回表格,

[global::System.Data.Linq.Mapping.FunctionAttribute(Name="PFO.PFOValidateUpdateData")]
        public ISingleResult<PFOValidData> PFOValidateUpdateData([global::System.Data.Linq.Mapping.ParameterAttribute(Name = "PfoIDs", DbType = "Xml")] System.Xml.Linq.XElement pfoIDs, [global::System.Data.Linq.Mapping.ParameterAttribute(Name = "UserID", DbType = "UniqueIdentifier")] System.Nullable<System.Guid> userID)
        {
            IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), pfoIDs, userID);
            return ((ISingleResult<PFOValidData>)(result.ReturnValue));
        }

And in the Domainservice 并在Domainservice中

List<string> PFOValidateUpdateData(string pfoIds, Guid userID)
        {
           List<string> productIdList = new List<string>();

      // Acquire the int  
               result = this.DataContext.PFOValidateUpdateData(element, userID);


               foreach (var item in result)
               {
                   productIdList.Add(item.ProductID);
               }
 return productIdList;

To get the multiple values returned by the stored procedure.... 要获取存储过程返回的多个值...。

Please let me know if there is a better way to solve this... thank you 请让我知道是否有更好的方法来解决此问题...谢谢

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

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