我有一个PC Enity,它有一些属性,我想基于属性返回一个不同的Object(PC或Complex Type或其他)的列表,以便将它绑定到像DropDownList这样的服务器控件。因为我的方法位于BLL我不能返回匿名类型,所以我创建了一个具有两个peroperties的Branch ComplexType。
我是这样写的,但它有重复的记录:List<Branch> result = ( from p in _context.PCs
where p.UserId== userId
select new Branch()
{
BranchId= p.BranchId,
BranchName=p.BranchName
}).Distinct().ToList();
修改: 谢谢大家,这很有效:
List<PC> result = _context.PCs
.GroupBy(p=>p.BranchName , p.BranchId})
.select(g=>g.First())
.ToList();
答案 0 :(得分:11)
这将为select语句中的所有列返回不同的行。如果您想要特定列的不同行,请指定该特定列
List<Branch> result = ( from p in _context.PCs
where p.UserId== userId
select new Branch()
{
BranchId= p.BranchId,
}).Distinct().ToList();
如果要基于多个列获取不同的值,则必须创建一个组,然后从该组中选择第一个值。在这种情况下,您不会使用Distinct,例如
List<Branch> distinctResult = _context.PCs
.GroupBy(p => new Branch {p.BranchId, p.BranchName} )
.Select(g => g.First())
.ToList();
答案 1 :(得分:3)
我无法重现该问题(使用SQL Server 2008 R2和EF 4.1 / DbContext进行测试)。您问题中的查询...
List<Branch> result = ( from p in _context.PCs
where p.UserId== userId
select new Branch()
{
BranchId = p.BranchId,
BranchName = p.BranchName
})
.Distinct()
.ToList();
...生成以下SQL:
SELECT
[Distinct1].[C1] AS [C1],
[Distinct1].[BranchId] AS [BranchId],
[Distinct1].[BranchName] AS [BranchName]
FROM ( SELECT DISTINCT
[Extent1].[BranchId] AS [BranchId],
[Extent1].[BranchName] AS [BranchName],
1 AS [C1]
FROM [dbo].[PCs] AS [Extent1]
) AS [Distinct1]
这两列都是DISTINCT,我得到了预期的不同结果 - BranchId
和BranchName
没有重复。
答案 2 :(得分:2)
您得到重复项,因为Distinct()无法将两个复杂的Branch对象识别为与其属性相同。它只是比较对象相等性,它将返回false(因为你创建了两个不同的对象,但具有相同的值)。
您可以使用Distinct(IQueryable, IEqualityComparer)提供自己的Comparer或实现IEquatable界面。
答案 3 :(得分:1)
这适合我。
<强> 1 强>
class RolBaseComparer:IEqualityComparer<RolBase>
{
public RolBaseComparer()
{
}
public bool Equals(RolBase x, RolBase y)
{
if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
{
return false;
}
if (Object.ReferenceEquals(x, y))
{
return true;
}
return x.Id.Equals(y.Id) &&
x.Nombre.Equals(y.Nombre);
}
public int GetHashCode(RolBase obj)
{
return obj.Id.GetHashCode() ^ obj.Nombre.GetHashCode();
}
}
<强> 2 强>
var ResultQuery = (from ES in DbMaster.Estudiantes
join I in DbMaster.Inscripciones on ES.strCedula equals I.strCedEstud
join C in DbMaster.Carreras on I.strCodCarrera equals C.strCodigo
where ES.strCedula.Equals(Cedula)
select new RolBase { Id = "EST", Nombre = "Estudiante" }).ToList();
第3 强>
return ResultQuery.Distinct(new RolBaseComparer()).ToList()