Ih, i am facing a problem with IEquatable (C#). As you can see in the following code, I got a class where i've implement IEquatable but it's "Equals" method is not getting reach. My objective is: I have a datetime column in my database and i would like to distinct only date, not considering the "time" part.
for example: 12-01-2014 23:14 would be equal to 12-01-2014 18:00.
namespace MyNamespace
{
public class MyRepository
{
public void MyMethod(int id)
{
var x = (from t in context.MyTable
where t.id == id
select new MyClassDatetime()
{
Dates = v.Date
}).Distinct().ToList();
}
}
public class MyClassDatetime : IEquatable<MyClassDatetime>
{
public DateTime? Dates { get; set; }
public bool Equals(MyClassDatetime other)
{
if (other == null) return false;
return (this.Dates.HasValue ? this.Dates.Value.ToShortDateString().Equals(other.Dates.Value.ToShortDateString()) : false);
}
public override bool Equals(object other)
{
return this.Equals(other as MyClassDatetime );
}
public override int GetHashCode()
{
int hashDate = Dates.GetHashCode();
return hashDate;
}
}
}
Have you know how can i make it work properly or other option to do what i need?? Thank you!!
Your implementation of GetHashCode
is incorrect for the desired equality semantics. That's because it returns different hash codes for dates that you want to compare equal, which is a bug .
To fix it, change it to
public override int GetHashCode()
{
return Dates.HasValue ? Dates.Value.Date.GetHashCode() : 0;
}
You should also update Equals
in the same spirit, it's not a good idea to mess with string representations of dates:
public bool Equals(MyClassDatetime other)
{
if (other == null) return false;
if (Dates == null) return other.Dates == null;
return Dates.Value.Date == other.Dates.Value.Date;
}
Update: As usr very correctly points out , since you are using LINQ on an IQueryable the projection and Distinct
call will be translated to a store expression and this code will still not run. To get around that you can use an intermediate AsEnumerable
call:
var x = (from t in context.MyTable
where t.id == id
select new MyClassDatetime()
{
Dates = v.Date
}).AsEnumerable().Distinct().ToList();
Thans for reply but it still not solving my problem.
I finally found a way to do it but without using IEquatable.
var x = (from t in context.MyTable where t.Id == id select EntityFunctions.CreateDateTime(t.Date.Value.Year, t.Date.Value.Month,t.Date.Value.Day, 0, 0, 0)).Distinct();
=)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.