一种搜索实体的方法,其特定属性与实体框架中的给定标准相匹配
本文关键字:实体 框架 属性 标准 一种 搜索 方法 | 更新日期: 2023-09-27 18:14:56
好吧,我不确定问题的标题是否足够清楚,但我想不出更简单的解释了。
我正在制作一个ASP的搜索页面。. NET web应用程序。我希望允许用户使用不同的过滤器进行搜索。
我想出了一个方法,根据用户选择的Categories类型过滤Publications(这些是用户将检索的实体)。
List<Publication> publications =
(from p in GetPublications()
where categories.Contains((int)p.CategoryId)
select p).ToList();
上面的linq查询等价于下面的sql查询:
select * from Publication p where p.CategoryId in (@chosenCategoryIds)
一切都很完美,但问题是我想让用户从更多的过滤器中选择,例如,不仅是类别,还有用户,标签,标题等。
如果我想要这个,我应该写很多条件语句来检查用户是否提供了给定的过滤器,比如:
if (categories != null)
{
var publications = (from p in GetPublications()
where categories.Contains((int)p.CategoryId)
select p).ToList();
if (users != null)
{
publications = (from p in publications
where users.Contains((int)p.UserId)
select p).ToList();
}
}
else
{
// Handle other situations..
}
结果是我对不同的过滤器做了相同的事情。我的问题是,是否有人知道或能想到更好的方法来实现这一点?如果没有,让我们看看下面的方法:
public List<InterpretumDAL.Publication> FilterPublications(List<InterpretumDAL.Publication> oldList, int[] values)
{
List<InterpretumDAL.Publication> newList =
(from p in oldList
where values.Contains((int)p.CategoryId)
select p).ToList();
return newList;
}
我试图用上面的方法实现的是通过给定的值数组过滤给定的列表。问题是,我不知道如何告诉方法要比较哪个属性,所以我可以这样调用它:
newList = FilterPublications(publications, categories, CATEGORY_PROPERTY_OF_PUBLICATION);
newList = FilterPublications(publications, users, USER_PROPERTY_OF_PUBLICATION);
newList = FilterPublications(publications, tags, TAG_PROPERTY_OF_PUBLICATION);
编辑:根据LiquidPony的回答,我是这样做的:
var publications = (from p in GetPublications()
where (
(categories == null || categories.Length == 0 || (p.CategoryId.HasValue && categories.Contains((int)p.CategoryId)))
&& (users == null || users.Length == 0 || users.Contains(p.UserId))
&& (tags == null || tags.Length == 0 || tags.Contains(p.TagId))
)
select p).ToList();
根据LiquidPony的回答,我认为使用三元运算符这样做会更好。
var query = from p in GetPublications()
where (
(categories != null ? categories.Contains((int)p.CategoryId) : true)
&& (users != null ? users.Contains((int)p.UserId) : true)
&& (tags != null ? tags.Contains((int)p.TagId) : true)
) select p;
如果没有提供其中一个变量,该语句将简单地求值为true,而不包括在SQL求值中(据我所知)。
除非绝对必要,否则要避免使用OR。在SQL中,它们的效率非常低,通常您可以找到一种替代方法来获得您想要的结果,而无需使用它们。
最简单的方法是这样做:
var query = from p in GetPublications()
where (
(categories == null || categories.Contains((int)p.CategoryId))
&& (users == null || users.Contains((int)p.UserId))
&& (tags == null || tags.Contains((int)p.TagId))
) select p;
如果你想匹配所有的条件,那就可以了。如果您希望返回只匹配一个条件的实体,则可以将&&
切换为||
。