2008-12-13 34 views
34

Làm thế nào tôi có thể chiếu số hàng vào tập kết quả truy vấn LINQ.Làm thế nào để chiếu một số dòng vào kết quả truy vấn LINQ

Thay vì nói:

field1, field2, field3

field1, field2, field3

Tôi muốn:

1, field1, field2, field3

2 , field1, field2, field3

Đây là nỗ lực của tôi tại đây:

public List<ScoreWithRank> GetHighScoresWithRank(string gameId, int count) 
{ 
    Guid guid = new Guid(gameId); 
    using (PPGEntities entities = new PPGEntities()) 
    { 
     int i = 1; 
     var query = from s in entities.Scores 
        where s.Game.Id == guid 
        orderby s.PlayerScore descending 
        select new ScoreWithRank() 
        { 
         Rank=i++, 
         PlayerName = s.PlayerName, 
         PlayerScore = s.PlayerScore 
        }; 
     return query.ToList<ScoreWithRank>(); 
    } 
} 

Thật không may, "Rank = i ++" dòng ném thời gian biên dịch ngoại lệ sau đây:

"Một cây biểu hiện có thể không chứa một toán tử gán"

+0

có thể trùng lặp của [Làm thế nào để bạn thêm một lĩnh vực chỉ số để kết quả LINQ] (http://stackoverflow.com/questions/269058/how-do-you-add-an-index-field- to-linq-results) –

Trả lời

55

Vâng, đơn giản nhất cách sẽ là để làm điều đó tại phía khách hàng chứ không phải là bên cơ sở dữ liệu, và sử dụng sự quá tải của Chọn cung cấp một chỉ số cũng như:

public List<ScoreWithRank> GetHighScoresWithRank(string gameId, int count) 
{ 
    Guid guid = new Guid(gameId); 
    using (PPGEntities entities = new PPGEntities()) 
    { 
     var query = from s in entities.Scores 
        where s.Game.Id == guid 
        orderby s.PlayerScore descending 
        select new 
        { 
         PlayerName = s.PlayerName, 
         PlayerScore = s.PlayerScore 
        }; 

     return query.AsEnumerable() // Client-side from here on 
        .Select((player, index) => new ScoreWithRank() 
          { 
           PlayerName = player.PlayerName, 
           PlayerScore = player.PlayerScore, 
           Rank = index + 1; 
          }) 
        .ToList(); 

    } 
} 
+3

nhận mọi thứ từ cơ sở dữ liệu, nó thực sự không phải là 'giải pháp' – Adaptabi

+1

@DotNetWise: Nó không nhận được * mọi thứ * từ cơ sở dữ liệu - chỉ có bit khớp với truy vấn. Nó chỉ nhận được cùng một lượng dữ liệu từ cơ sở dữ liệu như là nỗ lực ban đầu - chỉ cần thực hiện một chút xử lý sau. –

+0

Làm thế nào? query.AsEnumerable() sẽ nạp tất cả các bản ghi phù hợp cho gameId đã cho. Cố gắng chỉ nhận các vị trí xếp hạng sau 20. Bạn sẽ nhận được tất cả mọi thứ từ db để có thứ hạng và sau đó cắt ra những gì bạn cần. Không thực sự là giải pháp mong muốn! Khác với điều đó - thông số đếm được sử dụng ở đâu? – Adaptabi

1

Ok, mà đã làm các trick. Cảm ơn.

Đây là mã cuối cùng của tôi ...

Server:

public List<Score> GetHighScores(string gameId, int count) 
{ 
    Guid guid = new Guid(gameId); 
    using (PPGEntities entities = new PPGEntities()) 
    { 
     var query = from s in entities.Scores 
        where s.Game.Id == guid 
        orderby s.PlayerScore descending 
        select s; 
     return query.ToList<Score>(); 
    }                  
} 

Chủ đầu tư:

void hsc_LoadHighScoreCompleted(object sender, GetHighScoreCompletedEventArgs e) 
{ 
    ObservableCollection<Score> list = e.Result; 

    _listBox.ItemsSource = list.Select((player, index) => new ScoreWithRank() 
          { 
           PlayerName = player.PlayerName, 
           PlayerScore = player.PlayerScore, 
           Rank = index+=1 
          }).ToList(); 
} 
+0

Bạn có thực sự cần GetHighScores() để trả về một Danh sách thay vì một số điện thoại IEkhông? Nếu bạn định chuyển đổi nó thành một danh sách, bạn cũng có thể làm điều đó một lần. –

+0

@Jon: Anh ấy có thể gọi AsEnumerable thay vào đó nhưng ... Phương pháp AsEnumerable không có tác dụng khác ngoài việc thay đổi loại thời gian biên dịch của nguồn. http://msdn.microsoft.com/en-us/library/bb335435.aspx - nói cách khác, nó sẽ không đưa các đối tượng vào bộ nhớ. Nếu anh ta muốn kiểm soát điều đó, ToList là tốt –

+0

Có, nhưng chỉ * nếu * anh ấy cần phải làm điều đó tại thời điểm đó. Nếu anh ta không cần phải có không có điểm trong việc sao chép tất cả các dữ liệu hai lần. Do đó tính chất câu hỏi của đồng phân của tôi :) Trong thực tế, ngay cả AsEnumerable là không cần thiết của khóa học - nếu phương pháp GetHighScores được khai báo để trả về IEnumerable mà sẽ làm điều đó. –

0

Bạn cũng có thể làm chỉ là một điều chỉnh nhỏ để mã ban đầu của bạn để làm cho nó làm việc . Lời cảnh báo, nếu bạn databind hoặc truy cập vào đối tượng một lần nữa, Rank sẽ tăng mỗi lần. Trong những trường hợp đó, câu trả lời hàng đầu là tốt hơn.

let Rank = i++ 

Rank.ToString() 

Toàn mã:

public List<ScoreWithRank> GetHighScoresWithRank(string gameId, int count) 
{ 
Guid guid = new Guid(gameId); 
using (PPGEntities entities = new PPGEntities()) 
{ 
    int i = 1; 
    var query = from s in entities.Scores 
       let Rank = i++ 
       where s.Game.Id == guid 
       orderby s.PlayerScore descending 
       select new ScoreWithRank() 
       { 
        Rank.ToString(), 
        PlayerName = s.PlayerName, 
        PlayerScore = s.PlayerScore 
       }; 
    return query.ToList<ScoreWithRank>(); 
} 

}

+3

Mã này thậm chí sẽ không biên dịch. Nó tạo ra lỗi CS0832: Cây biểu thức có thể không chứa toán tử gán –

Các vấn đề liên quan