异常

yvfmudvl  于 2021-06-18  发布在  Mysql
关注(0)|答案(3)|浏览(320)

我正在尝试向mvc应用程序添加过滤器。我在这方面有点成功,因为我可以返回一个过滤后的值,如果它出现在db中的话。
但是,当它不存在于数据库中时,我希望它返回一个空列表。因为如果结果为零,linq应该返回空。但是,如果某个代码语句由于某种原因失败,并且输入的字段与任何db条目都不匹配,那么我使用try catch来捕获任何异常,linq查询将中断为catch,异常为null。
我不知道出了什么事,它甚至不应该闯入陷阱。
linq查询:

if (attr1 == "null" && attr3 != "null" && attr2 != "null")
    {
       attr1 = "%";

         Size = db.GetFilterResultCount(index, Size, attr1, attr2, attr3).Count();
         accountlist = db.GetFilterResult(index, Size, attr1, attr2, attr3).ToList();

         filteredlist.GetList = accountlist;
         filteredlist.index = index;
         filteredlist.size = Size;
         filteredlist.totalSize = db.Accounts.Count();
         filteredlist.resultSize = db.GetFilterResultCount(index, Size, attr1, attr2, attr3).Count();
    }

这是我用来检查哪个字段被过滤的众多条件之一。但是linq查询对于所有这些查询都是相同的。
存储过程:

CREATE PROCEDURE [dbo].[GetFilterResult]
@PageIndex INT,  
@pageSize INT,
@attr1 nvarchar(300),
@attr2 nvarchar(300),
@attr3 nvarchar(300)

    AS
    Begin
    SELECT  Accounts.firstName, Accounts.lastName, Accounts.Email, 
     Accounts.dateOfBirth, Accounts.phoneNo, Countries.CountryName 

    FROM Accounts INNER JOIN Countries On Accounts.CountryID = 
     Countries.CountryID

    Where (Accounts.firstName LIKE CONCAT('%', @attr1, '%') and 
     Accounts.lastName LIKE CONCAT('%', @attr2, '%') and Accounts.CountryID 
      Like CONCAT('%', @attr3, '%')) 

    ORDER BY UserId OFFSET @PageSize*(@PageIndex-1) ROWS FETCH NEXT 
     @PageSize ROWS ONLY;

    END

getfilterresultcount:

CREATE PROCEDURE [dbo].[GetFilterResult]
@PageIndex INT,  
@pageSize INT,
@attr1 nvarchar(300),
@attr2 nvarchar(300),
@attr3 nvarchar(300)

    AS
    Begin
    SELECT  Accounts.firstName, Accounts.lastName, Accounts.Email, 
     Accounts.dateOfBirth, Accounts.phoneNo, Countries.CountryName 

    FROM Accounts INNER JOIN Countries On Accounts.CountryID = 
     Countries.CountryID

    Where (Accounts.firstName LIKE CONCAT('%', @attr1, '%') and 
     Accounts.lastName LIKE CONCAT('%', @attr2, '%') and Accounts.CountryID 
      Like CONCAT('%', @attr3, '%')) 

    END
gwbalxhn

gwbalxhn1#

我发现了问题。try-catch没有很好地工作,我删除了它,并立即得到了一个异常,说明:“不能返回小于1的结果”或类似的东西。所以基本上结果至少需要1行以上,可能是因为这一行。

ORDER BY UserId OFFSET @PageSize*(@PageIndex-1) ROWS FETCH NEXT 
 @PageSize ROWS ONLY;

因此,我添加了一个先检查结果大小的条件,如果它是零,而不是使用上面的存储过程返回,我只返回一个空列表。

a1o7rhls

a1o7rhls2#

存储过程是一个简单的sql select。这意味着,如果没有与您的sql where匹配的项,则存储过程将返回一个空列表。
你忘了告诉我你要用哪种型号的 db ,尤其是 db.GetFilterResult . 这是你自己做的还是你自己做的 db 它自动知道要调用哪个存储过程。
如果是您自己创建的,它将类似于:

IEnumerable<Account> GetFilterResultCount(...)
{
     try
     {
          var fetchedData = CallStoredProcedure();
          foreach(var fetchedRow in fetchedData)
          {
              // use fetched data to create a new account object
              Account account = new Account() {... use fetchedData }
              yield return account;
          }
     }
     catch (Exception exc)
     {
         // TODO: decide what to do with this exception. Log and continue?
         // return empty sequence as if no Accounts where available
     }
}

如果存储过程返回空选择或异常,则返回空序列。如果对存储过程的调用返回 null 如果未选择任何内容(非常不寻常),则应检查空返回:

var fetchedData = CallStoredProcedure();
 if (fetchedData != null)
 {
     foreach(var fetchedRow in fetchedData) ...

有些人不喜欢用 yield 并且只喜欢linq(尽管linq内部会产生收益)。

try
{
    var fetchedData = CallStoredProcedure();
    if (fetchedData == null)
    {   // nothing fetched, return empty sequence
        return Enumerable.Empty<Account>();
    }
    else
    {
         return fetchedData.Select(fetchedRow => new Account() {...};
    }
}
catch (Exception exc)
{   // problem fetching data, return empty sequence
    return Enumerable.Empty<Account>();
}

如果你熟悉 yield return ,那么我不确定linq解决方案是否更具可读性/可维护性。
用法:

var accountlist = db.GetFilterResult(index, Size, attr1, attr2, attr3)
    .ToList();

如果你不能改变 db.GetFilterResult ,我想最好自己写

IEnumerable<Account> FetchFilterResultData(...)
{
     var fetchedData = db.GetFilterResult(...);
     // return emtpy sequence if null returned:
     return fetchedData ?? Enummerable.Empty<Account>();

     // TODO: exception handling needed?
}

用法:

var accountlist = this.FetchFilterResultData(index, Size, attr1, attr2, attr3)
    .ToList();
eanckbw9

eanckbw93#

这不是您的答案,但您正在尝试忽略attr1 where子句,此时attr1==“null”。您可以在查询中使用ifnull函数

Where (Accounts.firstName LIKE  CONCAT('%', IFNULL(@attr1, Accounts.firstName), '%') and

并将null传递给存储过程

attr1 = null;
   accountlist = db.GetFilterResult(index, Size, attr1, attr2, attr3).ToList();

相关问题