2012-04-02 29 views
11

Tôi có PC Enity có một số Thuộc tính, tôi muốn trả về một danh sách đối tượng riêng biệt (PC hoặc kiểu phức hoặc bất kỳ thứ gì) dựa trên thuộc tính để liên kết nó với điều khiển máy chủ Danh sách thả xuống . Và Bởi vì phương pháp của tôi nằm trong BLL tôi không thể trả về kiểu ẩn danh, Vì vậy, tôi đã tạo ra một BranchType Loại có hai peroperties.Entity Framework trả về các bản ghi riêng biệt

tôi đã viết như thế này nhưng nó có hồ sơ repeative:

List<Branch> result = (from p in _context.PCs 
         where p.UserId== userId 
         select new Branch() 
            { 
             BranchId= p.BranchId, 
             BranchName=p.BranchName 
            }).Distinct().ToList(); 

Edit: Cảm ơn tất cả các bạn, Đây làm việc:

List<PC> result = _context.PCs 
        .GroupBy(p=>p.BranchName , p.BranchId}) 
        .select(g=>g.First()) 
        .ToList(); 
+0

Bạn có nghĩa là bạn có hai yếu tố trong 'danh sách result' cái nào bằng nhau trong cả 'BranchId' AND' BranchName'? Điều này sẽ gây ngạc nhiên bởi vì điều đó không nên xảy ra với ví dụ của bạn. – Slauma

+0

Có Bạn nhận được đúng – Mostafa

+0

Bạn có sử dụng SQL Server không? Nếu có, phiên bản nào? Nếu không, cơ sở dữ liệu nào? – Slauma

Trả lời

9

này sẽ trả lại hàng khác nhau cho tất cả các cột trong câu lệnh chọn. Nếu bạn muốn hàng riêng biệt cho một cột cụ thể chỉ định rằng cột cụ thể

List<Branch> result = (from p in _context.PCs 
         where p.UserId== userId 
         select new Branch() 
            { 
             BranchId= p.BranchId, 
            }).Distinct().ToList(); 

Nếu bạn muốn nhận được giá trị khác biệt dựa trên nhiều cột, sau đó bạn phải tạo một nhóm và sau đó chọn giá trị đầu tiên từ nhóm đó. Trong trường hợp đó bạn sẽ không sử dụng riêng biệt, ví dụ

List<Branch> distinctResult = _context.PCs 
    .GroupBy(p => new Branch {p.BranchId, p.BranchName}) 
    .Select(g => g.First()) 
    .ToList(); 
+0

Cảm ơn. Mã đầu tiên không hoạt động, Nó trả về các bản ghi lặp lại cũng như tôi cần branchName. – Mostafa

+0

@Mostafa, thay thế BranchId, bằng BranchName trong statemet đầu tiên – Habib

+0

Thứ hai không hoạt động. Nó nhận được lỗi thời gian biên dịch: Không thể chuyển đổi loại Nguồn System.Collection.Generic.List <...Pc> thành loại mục tiêu System.Collection.Generic.List <...Branch> – Mostafa

2

Bạn nhận được bản sao vì Distinct() là không thể nhận ra hai đối tượng Chi nhánh phức tạp của bạn như giống hệt nhau từ tài sản của họ. Nó sẽ chỉ so sánh đối với bình đẳng đối tượng, nó sẽ trả về false (vì bạn tạo hai đối tượng khác nhau, nhưng với cùng giá trị).

Bạn có thể sử dụng Distinct(IQueryable, IEqualityComparer) để cung cấp Bộ so sánh của riêng bạn hoặc triển khai Giao diện IEquatable.

+0

Ví dụ trong câu hỏi là LINQ to Entities ('Distinct' của' IQueryable '), không phải LINQ to Objects (' Distinct' of 'IEnumerable '). So sánh bình đẳng đối tượng không áp dụng trong trường hợp này. – Slauma

+0

Bạn nói đúng, gọi tốt. Sai khác biệt() ở đây. Nhưng sẽ không [cung cấp một IEqualityComparer] (http://msdn.microsoft.com/en-us/library/bb356803.aspx) vẫn còn sửa chữa vấn đề của mình? – magnattic

+0

Không, vì quá tải 'Distinct' nhận' IEqualityComparer' không được hỗ trợ trong LINQ to Entities. Tôi thực sự rất bối rối tại sao ví dụ trong câu hỏi không hoạt động. Tôi sẽ kiểm tra nó ... – Slauma

2

Tôi không thể tạo lại sự cố (được thử nghiệm với SQL Server 2008 R2 và EF 4.1/DbContext). Các truy vấn trong câu hỏi của bạn ...

List<Branch> result = (from p in _context.PCs 
         where p.UserId== userId 
         select new Branch() 
         { 
          BranchId = p.BranchId, 
          BranchName = p.BranchName 
         }) 
         .Distinct() 
         .ToList(); 

... tạo ra SQL sau:

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] 

Nó là một DISTINCT trên cả hai cột và tôi nhận được kết quả rõ rệt mong đợi - không có bản sao ở BranchIdBranchName.

+0

Cảm ơn vì nỗ lực của bạn, Có lẽ đó là vì Khóa của Thực thể PC là PCId chứ không phải BranchId – Mostafa

1

Điều này phù hợp với tôi.

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() 
Các vấn đề liên quan