从Linq-to SQL调用存储过程时无效的转换

时间:2011-04-12 20:45:16

标签: sql-server linq stored-procedures .net

Linq-to-SQL业务层调用SQL存储过程并获取:

Unable to cast object of type 'WhereSelectEnumerableIterator`2
[ERICustomersDataLayer.MergeCustomersResult,ERICustomersDataLayer.MergeCustomersResult]' 
to type 'System.Collections.Generic.List`1[System.String]'.

存储过程:

ALTER PROCEDURE MergeCustomers @CurrentCustomerId UNIQUEIDENTIFIER, @MergedCustomerId UNIQUEIDENTIFIER
AS
BEGIN
    DECLARE @Error VARCHAR(500);
    IF NOT EXISTS (SELECT * FROM Customer WHERE Id = @CurrentCustomerId)
    BEGIN
        SET @Error = 'Current customer ID not in customer table '
        SELECT @Error [Error]
        RETURN -1
    END

    IF NOT EXISTS (SELECT * FROM Customer WHERE Id = @MergedCustomerId)
    BEGIN
        SET @Error = 'Merged customer ID not in customer table '
        SELECT @Error [Error]
        RETURN -1
    END
END

Linq-to-SQL代码:

public List<string> Merge(Guid CurrentUserId, Guid MergedUserId)
{
    var dc = new ERICustomersDataLayer.ERICustomersDataContext();
    var rows = (
            from e in dc.MergeCustomers(CurrentUserId, MergedUserId)
            select e);

    return (List<string>)rows;
}

在测试用例中,SP没有返回任何内容,因此这应该与空查询相同。但是,即使它确实返回错误消息,我也会得到相同的异常。

2 个答案:

答案 0 :(得分:2)

正如driis所说,linq没有返回列表,而是返回了IEnumerable的MergeCustomersResult。因此,您不能将其转换为List或只是执行.ToList()。您需要确保var“rows”是一个字符串列表,然后才能将其作为一个字符串返回。尝试这样的事情:

public List<string> Merge(Guid CurrentUserId, Guid MergedUserId) {
   var dc = new ERICustomersDataLayer.ERICustomersDataContext();
   var rows = (from e in dc.MergeCustomers(CurrentUserId, MergedUserId)               
              select e.Error);      
   return rows.ToList(); 
}

我不确定你的MergeCustomerResult是如何设置的,但我猜它有一个名为Error的属性,它映射到你在sp中返回的[Error]列。

答案 1 :(得分:1)

您的错误只是说它无法将结果强制转换为List。这是有道理的,因为LINQ查询不返回List,而是返回IQueryable(或IEnumerable),其实现基于实际表达式和底层提供者。

您可以轻松修复此错误。请尝试使用ToList扩展方法将其转换为列表:

return rows.ToList();