[英]Using .Select and .Where in a single LINQ statement
我需要使用 LINQ 從特定表中收集不同的 Id。 問題是我還需要一個 WHERE 語句,該語句應該僅根據我設置的要求過濾結果。 不得不如此頻繁地使用 LINQ 相對較新,但我或多或少地使用了以下代碼:
private void WriteStuff(SqlHelper db, EmployeeHelper emp)
{
String checkFieldChange;
AnIList tableClass = new AnIList(db, (int)emp.PersonId);
var linq = tableClass.Items
.Where(
x => x.UserId == emp.UserId
&& x.Date > DateBeforeChanges
&& x.Date < DateAfterEffective
&& (
(x.Field == Inserted)
|| (x.Field == Deleted)))
)
).OrderByDescending(x => x.Id);
if (linq != null)
{
foreach (TableClassChanges item in linq)
{
AnotherIList payTxn = new AnotherIList(db, item.Id);
checkFieldChange = GetChangeType(item.FieldName);
// Other codes that will retrieve data from each item
// and write it into a text file
}
}
}
我試圖為 var linq 添加 .Distinct 但它仍然返回重復的項目(意味着具有相同的 Id)。 我已經閱讀了很多網站,並嘗試在查詢中添加一個 .Select,但 .Where 子句卻中斷了。 還有其他文章,其中查詢與檢索值並將其放入 var 的方式有些不同。 我也嘗試使用 .GroupBy 但在使用 Id 作為鍵時我得到一個“至少一個對象必須實現 IComparable”。
該查詢實際上有效,我能夠從具有我需要的規范的列中輸出數據,但我似乎無法使 .Distinct 工作(這是唯一真正缺少的東西)。 我試圖創建兩個變量,其中一個觸發一個不同的調用,然后有一個嵌套的 foreach 以確保這些值是唯一的,但是成千上萬的記錄來收集性能影響是否太多了。
我也不確定是否必須覆蓋或使用 IEnumerable 來滿足我的要求,並認為我會問這個問題以防萬一有更簡單的方法,或者是否可以同時使用 .Select 和 .Where 工作在一個聲明中?
您是在Where()
還是之前添加了Select()
?
由於並發邏輯,您應該在后面添加它:
1 Take the entire table
2 Filter it accordingly
3 Select only the ID's
4 Make them distinct.
如果您先執行 Select,則 Where 子句只能包含 ID 屬性,因為所有其他屬性都已被編輯掉。
更新:為清楚起見,此運算符順序應該有效:
db.Items.Where(x=> x.userid == user_ID).Select(x=>x.Id).Distinct();
可能想在最后添加一個.toList()
但這是可選的:)
為了讓Enumerable.Distinct
適用於您的類型,您可以實現IEquatable<T>
並為Equals
和GetHashCode
提供合適的定義,否則它將使用默認實現:比較引用相等(假設您使用的是引用類型) .
從手冊:
Distinct(IEnumerable) 方法返回一個不包含重復值的無序序列。 它使用默認的相等比較器 Default 來比較值。
默認相等比較器 Default 用於比較實現 IEquatable 泛型接口的類型的值。 要比較自定義數據類型,您需要實現此接口並為該類型提供您自己的 GetHashCode 和 Equals 方法。
在您的情況下,您可能只需要比較 ID,但您可能還想比較其他字段,這取決於兩個對象“相同”對您意味着什么。
您也可以考慮使用morelinq 中的DistinctBy
。
請注意,這只是 LINQ to Objects,但我認為這就是您正在使用的。
另一種選擇是結合GroupBy
和First
:
var query = // your query here...
.GroupBy(x => x.Id)
.Select(g => g.First());
例如,這也適用於 LINQ to SQL。
由於您要比較兩個不同的對象,因此您首先需要實現 IEqualityComparer 接口。 下面是一個簡單的控制台應用程序的示例代碼,它使用了 IEqualityComparer 的不同且簡單的實現:
class Program
{
static void Main(string[] args)
{
List<Test> testData = new List<Test>()
{
new Test(1,"Test"),
new Test(2, "Test"),
new Test(2, "Test")
};
var result = testData.Where(x => x.Id > 1).Distinct(new MyComparer());
}
}
public class MyComparer : IEqualityComparer<Test>
{
public bool Equals(Test x, Test y)
{
return x.Id == y.Id;
}
public int GetHashCode(Test obj)
{
return string.Format("{0}{1}", obj.Id, obj.Name).GetHashCode();
}
}
public class Test
{
public Test(int id, string name)
{
this.id = id;
this.name = name;
}
private int id;
public int Id
{
get { return id; }
set { id = value; }
}
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
}
我希望這有幫助。
您是否將IEqualityComparer<T>
傳遞給.Distinct()
?
像這樣的東西:
internal abstract class BaseComparer<T> : IEqualityComparer<T> {
public bool Equals(T x, T y) {
return GetHashCode(x) == GetHashCode(y);
}
public abstract int GetHashCode(T obj);
}
internal class DetailComparer : BaseComparer<StyleFeatureItem> {
public override int GetHashCode(MyClass obj) {
return obj.ID.GetHashCode();
}
}
用法:
list.Distinct(new DetailComparer())
您可以像這樣使用 LINQ 輕松查詢
考慮這個 JSON
{
"items": [
{
"id": "10",
"name": "one"
},
{
"id": "12",
"name": "two"
}
]
}
像這樣把它放在一個名為json
的變量中,
JObject json = JObject.Parse("{'items':[{'id':'10','name':'one'},{'id':'12','name':'two'}]}");
您可以使用以下 LINQ 查詢從名稱為"one"
的項目中選擇所有 ID
var Ids =
from item in json["items"]
where (string)item["name"] == "one"
select item["id"];
然后,您將在 IEnumerable 列表中得到結果
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.