C# 实体框架返回不同的记录问题
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9979773/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Entity Framework returning distinct records issue
提问by Mostafa
I have a PC Enity which have some Properties , I would like to return a list of distinct Object (PC or Complex Type or whatever ) based on a property in order to bind it to server controls like DropDownList . And Because my method located in BLL I can't return anonymous type , So I created a Branch ComplexType which has two peroperties.
我有一个 PC 实体,它有一些属性,我想返回一个基于属性的不同对象(PC 或复杂类型或其他)的列表,以便将它绑定到像 DropDownList 这样的服务器控件。并且因为我的方法位于 BLL 中,我无法返回匿名类型,所以我创建了一个具有两个 peroperties 的 Branch ComplexType。
I wrote like this but it have repeative records:
我是这样写的,但它有重复的记录:
List<Branch> result = ( from p in _context.PCs
where p.UserId== userId
select new Branch()
{
BranchId= p.BranchId,
BranchName=p.BranchName
}).Distinct().ToList();
Edit :Thank you all , This worked :
编辑:谢谢大家,这有效:
List<PC> result = _context.PCs
.GroupBy(p=>p.BranchName , p.BranchId})
.select(g=>g.First())
.ToList();
采纳答案by Habib
this will return distinct rows for all the columns in the select statement. If you want distinct rows for a particular column just specify that particular column
这将为 select 语句中的所有列返回不同的行。如果您想要特定列的不同行,只需指定该特定列
List<Branch> result = ( from p in _context.PCs
where p.UserId== userId
select new Branch()
{
BranchId= p.BranchId,
}).Distinct().ToList();
If you want to get distinct values based on multiple columns, then you have to create a group and then pick first value from that group. In that case you will not use Distinct, for example
如果您想根据多个列获得不同的值,则必须创建一个组,然后从该组中选择第一个值。在这种情况下,您将不会使用 Distinct,例如
List<Branch> distinctResult = _context.PCs
.GroupBy(p => new Branch {p.BranchId, p.BranchName} )
.Select(g => g.First())
.ToList();
回答by magnattic
You get duplicates because Distinct()is unable to recognize two of your complex Branch objects as identical from their properties. It will just compare for object equality, which will return false (because you create two different objects, but with the same values).
您会得到重复项,因为Distinct()无法从它们的属性中识别出两个复杂的 Branch 对象是否相同。它只会比较对象相等性,这将返回 false(因为您创建了两个不同的对象,但具有相同的值)。
You can use Distinct(IQueryable, IEqualityComparer)to provide your own Comparer or implement the IEquatableInterface.
您可以使用Distinct(IQueryable, IEqualityComparer)来提供您自己的比较器或实现IEquatable接口。
回答by Slauma
I cannot reproduce the problem (tested with SQL Server 2008 R2 and EF 4.1/DbContext). The query in your question...
我无法重现该问题(使用 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();
... generates the following SQL:
... 生成以下 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]
It is a DISTINCT on both columns and I get the expected distinct result - no duplicates in BranchIdand BranchName.
这是两列鲜明而我得到预期的结果截然不同-在没有重复BranchId和BranchName。
回答by Joma
This works for me.
这对我有用。
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.
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.
3.
return ResultQuery.Distinct(new RolBaseComparer()).ToList()

