[英]Linq Expression to Select a Field
我有一個非常具體的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實例。
希望得到這個答案!
Cheerz,Anup
LINQ-to-SQL引擎無法知道Func<T, TProperty>
作用。
您需要接受Expression<Func<T, TProperty>>
,然后將表達式拼接成一個調用.Equals
的表達式。
代碼看起來像
Expression.Lambda<Func<T, TProperty>>(
Expression.Call(idProperty.Body, "Equals", new Type[0],
Expresion.Constant(uniqueId)),
idProperty.Parameters
)
此外,您應該更改您的方法以獲取IQueryable<T>
。
在閱讀了這兩條評論之后,我意識到應該使用IQueryable。 但是,Expression Call中的“Equals”不起作用,因為它會拋出以下錯誤:“類型'System.String'上的多個方法'Equals'與提供的參數兼容。” 因此我修改了一下代碼如下:
public static string GetUniqueId<T, TProperty>(this IQueryable<T> source, int length, Expression<Func<T, TProperty>> idProperty)
{
bool isUnique = false;
string uniqueId = String.Empty;
while (!isUnique)
{
uniqueId = PasswordGenerator.GenerateNoSpecialCharacters(length);
if (!String.IsNullOrEmpty(uniqueId))
{
var expr = Expression.Lambda<Func<T, bool>>(
Expression.Call(idProperty.Body, typeof(string).GetMethod("Equals", new[] { typeof(string) }), Expression.Constant(uniqueId)), idProperty.Parameters);
isUnique = source.SingleOrDefault(expr) == null;
}
}
return uniqueId;
}
這真的解決了這個問題。
實際上,如果您調用c.L2SOnlineCountMaster轉換為IEnumerable,將檢索所有記錄,如果您嘗試這樣做:
public static string GetUniqueId<T, TProperty>(this IQueryable<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.SingleOrDefault(i => idProperty(i).Equals(uniqueId)) == null;
}
}
return uniqueId;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.