web-dev-qa-db-ja.com

個別のレコードの問題を返すエンティティフレームワーク

いくつかのプロパティを持つPCエンティティがあります。DropDownListなどのサーバーコントロールにバインドするために、プロパティに基づいて個別のオブジェクト(PCまたは複合型など)のリストを返したいと思います。また、私のメソッドはBLLにあるため、匿名型を返すことができないため、2つのperoperityを持つBranchComplexTypeを作成しました。

私はこのように書いたが、それは繰り返しの記録を持っている:

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();
12
Mostafa

これにより、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(); 
11
Habib

問題を再現できません(SQL Server 2008R2およびEF4.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であり、期待される明確な結果が得られます。BranchIdBranchNameに重複はありません。

3
Slauma

Distinct() が2つの複雑なBranchオブジェクトをそれらのプロパティから同一であると認識できないため、重複が発生します。オブジェクトが等しいかどうかを比較するだけで、falseが返されます(2つの異なるオブジェクトを作成しますが、値は同じであるため)。

Distinct(IQueryable、IEqualityComparer) を使用して、独自のComparerを提供するか、 IEquatable インターフェイスを実装できます。

2
magnattic

これは私のために働きます。

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();

return ResultQuery.Distinct(new RolBaseComparer()).ToList()
1
Joma