Sea*_*ean 4 c# linq linq-to-entities distinct
我的自定义比较器似乎不起作用.我想要一些不同的对象,但我每次都得到1.即使查看数据库本身清楚地显示查询还有1个具有不同"TimeOfAction"值的实例.
class TimeComparer : IEqualityComparer<Action>
{
public bool Equals(Action a, Action b)
{
if (a.TimeOfAction == b.TimeOfAction)
return true;
else
return false;
}
public int GetHashCode(Action obj)
{
return obj.ToString().ToLower().GetHashCode();
}
}
Run Code Online (Sandbox Code Playgroud)
认为它可能是GetHashCode方法,因为我不太熟悉它的工作方式.这是linq查询.我转换为AsEnumerable,因为Linq to Entities不支持distinct方法.
DBEntities db = new DBEntities();
IEnumerable<Action> query =
from action in db.Action.AsEnumerable()
where action.TimeOfAction > new DateTime(2010, 11, 1, 0, 0, 0)
where action.TimeOfAction < new DateTime(2011, 2, 7, 0, 0, 0)
where action.EntityName == "seant"
select action;
var count = query.
Distinct(new TimeComparer()).Count();
Run Code Online (Sandbox Code Playgroud)
您的Equals和GetHashCode方法采用完全不同的方法.特别是,假设Action.ToString使用除TimeOfAction之外的字段,则相等的对象可能具有不同的哈希码.他们必须协调一致,否则你将无法获得合理的结果.不等对象可以使用相同的哈希码(尽管这会妨碍性能),但是相等的对象必须提供相同的哈希码.
请注意,使用自定义比较器将强制Distinct部分在进程内而不是在数据库中完成.这可能不是问题,你只需要了解它.编辑:我还没有发现这有一个超载的Queryable.Distinct这确实需要一个IEqualityComparer<T>.我的猜测是,你可以提供自定义字符串比较器和一些其他众所周知的比较器...而不仅仅是任意代码.如果它有效,它无论如何都将在本地完成.如果只是爆炸,我不会感到惊讶.
编辑:正如Marc所说,您可以Select(x => x.TimeOfAction).Distinct().Count()在数据库中使用它.你也需要删除这个电话AsEnumerable.我的猜测就是那里,因为其他东西不起作用.你可以试试这个:
DBEntities db = new DBEntities();
IQueryable<DateTime> query =
from action in db.Action
where action.TimeOfAction > new DateTime(2010, 11, 1, 0, 0, 0)
where action.TimeOfAction < new DateTime(2011, 2, 7, 0, 0, 0)
where action.EntityName == "seant"
select action.TimeOfAction;
var count = query.Distinct().Count();
Run Code Online (Sandbox Code Playgroud)
当然,如果您需要query其他东西,您还需要保留原始版本:
DBEntities db = new DBEntities();
IQueryable<Action> query =
from action in db.Action
where action.TimeOfAction > new DateTime(2010, 11, 1, 0, 0, 0)
where action.TimeOfAction < new DateTime(2011, 2, 7, 0, 0, 0)
where action.EntityName == "seant"
select action;
var count = query.Select(x => x.TimeOfAction).Distinct().Count();
// Use query here as well to get at full action details
Run Code Online (Sandbox Code Playgroud)
请注意,再次使用查询将产生第二个数据库查询.如果您需要计数与第二个查询所做的一致...或者从数据库中提取所有详细信息(使用ToList调用)然后执行Distinct部分,则需要查看事务中发生的情况进程.
回到自定义平等比较器......
假设TimeOfAction是一个DateTime或其他具有合理哈希码的类型,您可以将您的类更改为:
class TimeComparer : IEqualityComparer<Action>
{
public bool Equals(Action a, Action b)
{
return a.TimeOfAction == b.TimeOfAction;
}
public int GetHashCode(Action obj)
{
return obj.TimeOfAction.GetHashCode();
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,我也简化了您的Equals方法 - 只要您发现自己:
if (condition)
{
return true;
}
else
{
return false;
}
Run Code Online (Sandbox Code Playgroud)
你可以简化它:
return condition;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3105 次 |
| 最近记录: |