1

我正在研究Pro ASP.NET MVC 3 Framework中的 SportsStore 示例。在第 8 章的开头,我被指示编辑我的 ProductController 类,添加 .Where 行,如下所示:

    public ViewResult List(string category, int page = 1)
    {
        ProductsListViewModel viewModel = new ProductsListViewModel
        {
            Products = repository.Products
                .Where(p => category == null || p.Category == category)
                .OrderBy(p => p.ProductID)
                .Skip((page - 1) * PageSize)
                .Take(PageSize),
            PagingInfo = new PagingInfo
            {
                CurrentPage = page,
                ItemsPerPage = PageSize,
                TotalItems = repository.Products.Count()
            },
            CurrentCategory = category
        };
        return View(viewModel);
    }

当我运行代码时,我收到以下错误:

Exception Details: System.Data.SqlServerCe.SqlCeException: The specified argument
value for the function is not valid. [ Argument # = 1,Name of
function(if known) = isnull ]

在以下代码块的 foreach 行上:

@model SportsStore.WebUI.Models.ProductsListViewModel

@{
    ViewBag.Title = "Products";
}

@foreach (var p in Model.Products)
{
    Html.RenderPartial("ProductSummary", p);
}
<div class="pager">
    @Html.PageLinks(Model.PagingInfo, x => Url.Action("List", new {page = x}))
</div>

我已经搜索了很多,并在多个地方发现了很多对这个 StackOverflow 帖子的引用,但是将查询更改为

.Where(p => category == null ? true : p.Category == category)

没有效果。

一些基本信息:

  • 这是一个使用 Razer 视图引擎和 C# 的 MVC3 项目。
  • 我的 SQL Compact 4.0 数据库中的所有项目都有一个类别。
  • 注释掉 category == null 位会使代码运行得很好。
  • 我上面给出的第二个版本是他们网站上可下载的源代码。

它确实可以在没有空值检查的情况下工作,但我担心如果我继续前进,我以后可能会遇到问题。有人对我如何解决它有任何想法吗?

4

3 回答 3

1

我认为问题在于 LINQ 查询被推迟到它到达 SQL 服务器。我的猜测是 SQL compact 服务器在检查category == null.

在调用 Where 方法之前尝试使用非延迟 LINQ 方法。就像是

Products = repository.Products.ToList()
    .Where(p => category == null || p.Category == category)
    .OrderBy(p => p.ProductID)
    .Skip((page - 1) * PageSize)
    .Take(PageSize);
于 2012-08-08T21:07:36.020 回答
1

同样的问题,但标记的答案对我不起作用,因为我的 WHERE 子句位于我不想在结果中返回的相关表上。此外,返回所有内容然后执行 .Where() 效率非常低。

这是一个更好的方法:

SQL CE不能处理参数so,so标准构造

.Where(p => p.Category == category || category == null)

失败,因为 LINQ 需要使用参数在查询中进行值比较。但是传递这样的东西是完全有效的 SQL:

.Where(p => p.Category == category || true)

因为“真实”总是……嗯……真实。因此,如果您在 LINQ 语句之前将变量解析为布尔值,然后将该变量传递给 SQL CE,那么您的状态就很好:

bool bCategory = (string.IsNullOrEmpty(category)) ? true : false;

Products = repository.Products.Where(p => p.Category == category || bCategory);

这允许您在返回数据之前对查询中的所有过滤进行操作,并且您可以根据需要在尽可能多的条件上使用此技巧,而不会变得混乱。

于 2013-03-21T21:50:58.473 回答
0

不太确定它是否给出相同的输出,我认为它应该看看这个......

 Products = repository.Products
            .Where(p => p.Category == null || p.Category == category)
            .OrderBy(p => p.ProductID)
            .Skip((page - 1) * PageSize)
            .Take(PageSize),
于 2012-08-08T17:49:34.637 回答