我有一个非常具体的LINQ查询。我想检查表中是否存在随机生成的键。
标准查询可以定义为Select * from Products where SaleId == 'XXXXXXX'
。在这个查询中,XXXXXX由随机字符生成器生成(也提供了长度)。我创建了以下LINQ扩展:
public static string GetUniqueId<T, TProperty>(this IEnumerable<T> source, int length, Func<T, TProperty> idProperty)
{
bool isUnique = false;
string uniqueId = String.Empty;
while (!isUnique)
{
uniqueId = PasswordGenerator.GenerateNoSpecialCharacters(length);
if (!String.IsNullOrEmpty(uniqueId))
{
isUnique = source.AsQueryable().SingleOrDefault(i => idProperty(i).Equals(uniqueId)) == null;
}
}
return uniqueId;
}
但是,我注意到这个方法首先从作为源传递的表中选择所有记录,然后运行Where子句,这种行为显然非常耗时,所以基本上它执行SELECT * FROM Products
,然后运行SingleOrDefault
是否有任何方法可以直接运行查询,使其从产品中选择 * WHERE Id = 'XXXXXXX'
下面是我如何称呼它的一个例子:
string id = c.L2SOnlineCountMasters.GetUniqueId(9, x => x.MID);
在本例中,L2SOnlineCountMasters是数据库中的表,c是DataContext示例。
3条答案
按热度按时间qaxu7uf21#
在阅读了这两个注解之后,我意识到应该使用IQueryable。但是,表达式调用中的“Equals”不起作用,因为它会抛出以下错误:“类型'System.String'上有多个方法'Equals'与提供的参数兼容。”因此,我对代码做了如下修改:
这真的解决了问题。
soat7uwm2#
LINQ-to-SQL引擎无法知道
Func<T, TProperty>
的功能。您需要接受一个
Expression<Func<T, TProperty>>
,然后将表达式拼接成一个调用.Equals
的表达式。该代码类似于
此外,您还应该更改方法以获取
IQueryable<T>
。v8wbuo2f3#
实际上,如果调用c.L2SOnlineCountMasters强制转换为IEnumerable,将检索所有记录,如果尝试以下操作会怎样: