我正在研究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>
我搜索了很多,在多个地方发现了很多对this StackOverflow post的引用,但是将查询更改为
.Where(p => category == null ? true : p.Category == category)
没有效果。
一些基本信息:
没有空检查它确实有效,但我担心如果我继续前进我可能会在以后遇到问题。有没有人对我如何解决它有任何想法?
答案 0 :(得分:1)
我认为问题是LINQ查询被推迟到它到达SQL服务器。我的猜测是SQL紧凑型服务器在检查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);
答案 1 :(得分:1)
同样的问题,但标记的答案对我不起作用,因为我的WHERE子句在相关的表上,我不想在结果中返回。此外,返回所有内容然后再执行.Where()效率非常低。
这是一个更好的方法:
SQL CE无法处理参数,所以标准构造
.Where(p => p.Category == category || category == null)
失败,因为LINQ需要使用参数来进行查询中的值比较。但是传递这样的东西是完全有效的SQL:
.Where(p => p.Category == category || true)
因为'真'总是......好......真的。因此,如果您在LINQ语句之前将变量解析为bool,然后将该变量传递给SQL CE,那么您的状态良好:
bool bCategory = (string.IsNullOrEmpty(category)) ? true : false;
Products = repository.Products.Where(p => p.Category == category || bCategory);
这允许您在返回数据之前对查询中的所有过滤进行操作,并且可以在任意条件下使用此技巧,而不会使其变得混乱。
答案 2 :(得分:0)
不确定它是否提供相同的输出,我认为应该看看这个......
Products = repository.Products
.Where(p => p.Category == null || p.Category == category)
.OrderBy(p => p.ProductID)
.Skip((page - 1) * PageSize)
.Take(PageSize),