正在使用.选择和.单个LINQ语句中的Where
本文关键字:语句 LINQ Where 单个 选择 | 更新日期: 2023-09-27 18:25:28
我需要使用LINQ从特定表中收集Distinct 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的区别,但它仍然返回重复的项(意味着具有相同的Id)。我浏览了很多网站,并尝试添加了一个。在查询中选择,但选择。取而代之的是Where子句中断。在其他文章中,查询检索值并将其放置在变量中的方式在某种程度上有所不同。我也尝试过使用。GroupBy,但当使用Id作为键时,我得到一个"至少有一个对象必须实现IComparable"。
查询实际上是有效的,并且我能够根据我需要的规范输出列中的数据,但我似乎做不到。独特的作品(这是唯一真正缺少的东西)。我试图创建两个vars,其中一个触发一个不同的调用,然后有一个嵌套的foreach来确保值是唯一的,但会有数千条记录来收集性能影响太大了。
我也不确定我是否必须重写或使用IEnumerable来满足我的需求,我想我会问这个问题,以防有更简单的方法,或者两者都有可能。选择和。只在一个声明中工作在哪里?
是否在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列表