我在数据库中有一个Products和Category表:
产品包含以下列: ProductId,ProductName,Description,Path,Name,URL,CategoryId,Active
类别包含以下列: CategoryId,CategoryName
我编写了一个LINQ语句来查询数据库并获取相关类别的产品。查询工作正常。
public IQueryable<Product> GetProducts(
[QueryString("id")] int? categoryId,
[RouteData] string categoryName)
{
var _db = new products.Models.ProductContext();
IQueryable<Product> query = _db.Products;
if (categoryId.HasValue && categoryId > 0)
{
query = query.Where(p => p.CategoryID == categoryId);
}
if (!String.IsNullOrEmpty(categoryName))
{
query = query.Where(p =>
String.Compare(p.Category.CategoryName,
categoryName) == 0);
}
return query;
}
我有两个疑问:
如何修改此查询以仅选择那些Active = 1的产品。
目前,查询以特定顺序返回行,我认为该行基于productId - 1,2,3,4,5等。如何将结果混洗,以便不按特定顺序返回结果。它可能是5,2,4,1,3或下一次运行3,5,1,4,2等等。
答案 0 :(得分:0)
要过滤Active产品,只需按以下方式扩展查询:
query = query.Where(p => p.CategoryID == categoryId && p.Active == 1);
要改变结果,您必须自己编写代码。它可能是这样的:
var shuffledList = new List<Product>();
var originalList = query.ToList();
var random = new Random();
while (originalList.Count() > 0) {
var pick = random.Next(0, originalList.Count());
var product = originalList[pick];
shuffledList.Add(product);
originalList.Remove(product);
}
shuffledList
将按随机顺序包含您的商品。但是你会记住一些内存,因为你的内存中有两倍的产品。
我刚遇到的另一种可能性是:
var random = new Random();
query = query.OrderBy(product => random.Next());
答案 1 :(得分:0)
首先,洗牌部分。它不能用IQueryable
来完成,所以最好引入一个通用的扩展方法是一些常见的地方:
public static void Swap<T>(ref T x, ref T y)
{
var temp = x;
x = y;
y = temp;
}
public static T[] RandomShuffle<T>(this IEnumerable<T> source)
{
var result = source.ToArray();
if (result.Length < 2) return result;
var random = new Random();
for (int i = result.Length - 1; i > 0; i--)
{
int pos = random.Next(i + 1);
if (pos != i) Swap(ref result[pos], ref result[i]);
}
return result;
}
现在你的功能:
public IQueryable<Product> GetProducts(
[QueryString("id")] int? categoryId,
[RouteData] string categoryName)
{
var _db = new products.Models.ProductContext();
IQueryable<Product> query = _db.Products;
query = query.Where(p => p.Active == 1); // the first question
if (categoryId.HasValue && categoryId > 0)
{
query = query.Where(p => p.CategoryID == categoryId);
}
if (!String.IsNullOrEmpty(categoryName))
{
query = query.Where(p =>
String.Compare(p.Category.CategoryName,
categoryName) == 0);
}
return query;
}
您可以保持这种方式(IMO更好)并在您需要该行为时在呼叫方应用随机播放,例如GetProducts(....).RandomShuffle()
。或者,如果您坚持在内部进行,只需将最后一行更改为return query.RandomShuffle().AsQueryable();