我在使用IEnumerable和LINQ時遇到困難。也許我不完全理解它。LINQ問題難度
我有假文件(「PlumFile」)和一些過濾器的數據源。每個篩選器都有一個Fits(PlumFile)
,用於確定參數是否適合該篩選器。每個過濾器還有一個枚舉指示它是「和」,「或」還是「不」。
這裏是我怎樣,我想所有這些過濾器組合成一個查詢:
public ObservableCollection<PlumFile> FoundFiles
{
get
{
ObservableCollection<PlumFile> searchResults = new ObservableCollection<PlumFile>();
// get the data source
IEnumerable<PlumFile> query = PlumData.GetFiles();
foreach (FilterConstraint filter in filters)
{
// debugging
IList<PlumFile> oldQuery = query.ToList();
switch (filter.QueryCombiningRule)
{
case FilterConstraint.QueryRule.And:
query = query.Where(file => filter.Fits(file));
break;
case FilterConstraint.QueryRule.Or:
query = query.Concat(PlumData.GetFiles().Where(file => filter.Fits(file)));
break;
// is this really how I want to do 'not'?
case FilterConstraint.QueryRule.Not:
query = query.Where(file => !filter.Fits(file));
break;
}
// debugging
IList<PlumFile> currQuery = query.ToList();
}
query = query.Distinct();
foreach (PlumFile file in query)
{
searchResults.Add(file);
}
return searchResults;
}
}
我不知道我在做什麼錯。對於某些查詢,它工作正常。對於其他人,它失敗了。
如果我有一個「和」過濾器,它工作正常。然後我添加一個「不」過濾器,該過濾器不應該過濾掉已經選擇的任何東西,但是一切都被刪除了。爲什麼是這樣?
(我這樣做是爲Silverlight 4應用程序,但我不認爲它很重要。)
更新:
public class NameFilterConstraint : FilterConstraint
{
public string Name { get; set; }
public override bool Fits(PlumFile plumFile)
{
return plumFile.Name.Contains(Name);
}
public override string Description
{
get
{
return ToString();
}
}
public override string ToString()
{
return String.Format("Name contains '{0}'", Name);
}
}
:過濾約束 一個例子更新2:這是一個非LINQ版本,沒有我前面提到的錯誤:
public ObservableCollection<PlumFile> FoundFiles
{
get
{
ObservableCollection<PlumFile> searchResults = new ObservableCollection<PlumFile>(PlumData.GetFiles().ToList());
foreach (FilterConstraint filter in filters)
{
switch (filter.QueryCombiningRule)
{
case FilterConstraint.QueryRule.And:
foreach (PlumFile file in searchResults.ToList())
{
if (! filter.Fits(file))
{
searchResults.Remove(file);
}
}
break;
case FilterConstraint.QueryRule.Or:
foreach (PlumFile file in PlumData.GetFiles())
{
if (filter.Fits(file))
{
searchResults.Add(file);
}
}
break;
case FilterConstraint.QueryRule.Not:
foreach (PlumFile file in searchResults.ToList())
{
if (filter.Fits(file))
{
searchResults.Remove(file);
}
}
break;
}
}
return new ObservableCollection<PlumFile>(searchResults.Distinct());
}
}
所以,我想我的問題已經解決了,儘管我仍然對LINQ的做法感到好奇。也許我的意圖(在最後一個例子中已經明確)沒有正確地轉換成LINQ?
你可以包含適合Fits方法的代碼嗎? – Mark 2010-12-02 18:20:55
我花了5分鐘盯着這個,但我的大腦傷害只是看着問題,因爲它:) – Contango 2010-12-02 18:21:53
@Gravitas:是因爲我濫用LINQ?我怎樣才能以一種不太複雜的方式做到這一點? – 2010-12-02 18:38:15