简体   繁体   English

LINQ查询未返回唯一行

[英]LINQ query not returning unique rows

I have this LINQ query which queries SQL Express database through Entity Framework but doesn't return unique rows when written this way in Visual Studio: 我有此LINQ查询,该查询通过实体框架查询SQL Express数据库,但在Visual Studio中以这种方式编写时不返回唯一行:

var q = from s in _db.SD
        where s.ID == ID && s.Time >= startDate && s.Time <= endDate
        select s

It returns correct number of rows but each row has same data as first one. 它返回正确的行数,但每一行都具有与第一行相同的数据。 However, when I tested the same query in LinqPad the result returned is fine ie correct number of rows and unique data in each row. 但是,当我在LinqPad中测试相同的查询时,返回的结果很好,即正确的行数和每行中的唯一数据。

Secondly, if I try to change the statment to this: 其次,如果我尝试将陈述更改为:

var q = from s in _db.SD
        where s.ID == ID && s.Time >= startDate && s.Time <= endDate
        select s.Data

Then I got correct number of rows and unique value in each row. 然后我得到正确的行数,并且每行都有唯一的值。 Can someone please help me find out the problem with code? 有人可以帮我找出代码问题吗?

Thanks in advance. 提前致谢。 EDIT: Here's full function: 编辑:这是全部功能:

public List<SD> GetHistory(int ID, DateTime startDate, DateTime endDate)
{
    var q = (from s in _db.SD
            where s.ID == ID &&
            s.Time >= startDate && s.Time <= endDate
            select s).ToList();

   return q;
}

As you are getting correct distinct data using select s.Data , then you can write a Comparer class implementing IEqualityComparer<> inside the SD class as follows: 当使用select s.Data获取正确的不同数据时,可以编写一个在SD类内实现IEqualityComparer<>Comparer类,如下所示:

public class SD
{
    public Int16 ID { get; set; }

    public Byte MT { get; set; }
    public Byte Data { get; set; }
    public Byte SS { get; set; }
    public DateTime Time { get; set; }

    public class Comparer : IEqualityComparer<SD>
    {
        public bool Equals(SD x, SD y)
        {
            return x.Data == y.Data; // look...here I m using 'Data' field for distinction
        }

        public int GetHashCode(SD obj)
        {
            unchecked  // overflow is fine
            {
                int hash = 17;
                hash = hash * 23 + obj.Data.GetHashCode();
                return hash;
            }
        }
    }
}

Then you can write the GetHistory() method passing the Comparer in the Distinct() method as follows: 然后,你可以写GetHistory()方法传递ComparerDistinct()方法如下:

public List<SD> GetHistory(int ID, DateTime startDate, DateTime endDate)
{
    var list = new List<SD>();
    var q = (from s in list
                where s.ID == ID &&
                s.Time >= startDate && s.Time <= endDate
                select s).Distinct(new SD.Comparer()).ToList();

    return q;
}

EDIT 编辑

The regular query uses the default (reference equality) for checking whether two objects are equal or not. 常规查询使用默认值(引用相等)检查两个对象是否相等。

So, in order to make Distinct() work the way you want, you have to implement IEqualityComparer<T> . 因此,为了使Distinct()以您想要的方式工作,您必须实现IEqualityComparer<T> Otherwise, it will use the default (reference equality) for checking, which means it would only determine the elements were not distinct if they were the same exact instance. 否则,它将使用默认值(引用相等)进行检查,这意味着它只会确定元素是否相同,如果它们是相同的实例,则它们是不同的。 See the reference here. 请参阅此处的参考。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM