![](/img/trans.png)
[英]How to call a method in the where clause of a LINQ query on a IQueryable object
[英]Call method immediately after object construction in LINQ query
我有一些實現這個接口的對象:
public interface IRow
{
void Fill(DataRow dr);
}
通常當我從db中選擇一些東西時,我會去:
public IEnumerable<IRow> SelectSomeRows
{
DataTable table = GetTableFromDatabase();
foreach (DataRow dr in table.Rows)
{
IRow row = new MySQLRow(); // Disregard the MySQLRow type, it's not important
row.Fill(dr);
yield return row;
}
}
現在使用.Net 4,我想使用AsParallel,從而使用LINQ。
我已經對它進行了一些測試,並且它加速了很多東西(IRow.Fill使用Reflection,因此在CPU上很難)
無論如何我的問題是,我如何創建一個LINQ查詢,它調用Fills作為查詢的一部分,所以它是否正確並行化?
為了測試性能,我創建了一個構造函數,它將DataRow作為參數,但是如果可能的話,我真的很想避免這種情況。
有了構造函數,它顯然很簡單:
public IEnumerable<IRow> SelectSomeRowsParallel
{
DataTable table = GetTableFromDatabase();
return from DataRow dr in table.Rows.AsParallel()
select new MySQLRow(dr);
}
但是就像我說的,我真的很想能夠將我的Fill方法填充到LINQ查詢中,因此不需要構造函數重載。
你需要創建一個多語句lambda表達式,如下所示:
table.AsEnumerable().AsParallel().Select(dr =>
IRow row = new MySQLRow();
row.Fill(dr);
return row;
});
答案很幸運很簡單。 就這么做:)沒有什么可以阻止你在查詢的選擇部分中簡單地調用一個方法
public IEnumerable<IRow> SelectSomeRowsParallel
{
DataTable table = GetTableFromDatabase();
return from DataRow dr in table.Rows.AsParallel()
select (row =>
var mysqlRow = new MySQLRow()
mysqlRow.Fill(row);
return mysqlRow;)
}
如果你不能把它分配給Func,我不確定你能把lambda放在那里(自從我有機會寫LINQ以來已經有幾年了)
Func<IRow,DataRow> getRow =
(row =>
var mysqlRow = new MySQLRow()
mysqlRow.Fill(row);
return mysqlRow;)
然后在你的select子句中調用它
我認為沒有辦法將命令式操作(例如調用返回void
的Fill
方法)放入LINQ查詢語法中,但是你可以使用顯式調用Select
方法做同樣的事情,它允許你使用任意代碼:
DataTable table = GetTableFromDatabase();
return table.Rows.Cast<DataRow>().AsParallel().Select(dr => {
IRow row = new MySQLRow();
row.Fill(dr);
return dr; });
您需要添加對Cast
的調用(因為DataSet不實現IEnumerable
通用版本),其余的代碼非常簡單。 您的原始查詢將轉換為這些調用。
如果你想做一些技巧,你可以修改界面,這樣Fill
方法返回一些東西(例如int
)。 然后你可以使用let
子句並忽略返回的值。
return from DataRow dr in table.AsParallel()
let IRow row = new MySQLRow()
let _ = row.Fill(dr) // ignoring return value; '_' is just variable name
select row;
可以使用返回某些內容的技巧調用方法,但不能使用返回void
方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.