正在使用.选择和.单个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来满足我的需求,我想我会问这个问题,以防有更简单的方法,或者两者都有可能。选择和。只在一个声明中工作在哪里?

正在使用.选择和.单个LINQ语句中的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>并为EqualsGetHashCode提供合适的定义,否则它将使用默认实现:比较引用相等(假设您使用的是引用类型)。

来自手册:

Distinct(IEnumerable)方法返回一个不包含重复值的无序序列。它使用默认的相等比较器default来比较值。

默认的相等比较器default用于比较实现IEquatable泛型接口的类型的值。要比较自定义数据类型,您需要实现此接口,并为该类型提供自己的GetHashCode和Equals方法。

在您的情况下,您可能只需要比较ID,但也可能需要比较其他字段,这取决于两个对象"相同"对您的意义。

您也可以考虑使用morelinq中的DistinctBy

请注意,这只是LINQ to Objects,但我认为这就是您正在使用的内容。

还有一种选择是将GroupByFirst:结合起来

 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列表

中得到结果