2013-03-13 26 views
6

Tôi có truy vấn này LINQ:Làm thế nào để sửa đổi chỉ một hoặc hai trường trong dự báo LINQ?

List<Customers> customers = customerManager.GetCustomers(); 

return customers.Select(i => new Customer { 
    FullName = i.FullName, 
    Birthday = i.Birthday, 
    Score = i.Score, 
    // Here, I've got more fields to fill 
    IsVip = DetermineVip(i.Score) 
}).ToList(); 

Nói cách khác, tôi chỉ muốn một hoặc hai lĩnh vực của danh sách các khách hàng phải được sửa đổi dựa trên một điều kiện, trong phương thức kinh doanh của tôi. Tôi đã có hai cách để thực hiện điều này,

  1. Sử dụng for...each vòng lặp, để lặp qua khách hàng và sửa đổi lĩnh vực (phương pháp bắt buộc)
  2. Sử dụng LINQ chiếu (cách tiếp cận declarative)

Có bất kỳ kỹ thuật nào được sử dụng trong truy vấn LINQ, để chỉ sửa đổi một thuộc tính trong phép chiếu? Ví dụ: một cái gì đó như:

return customers.Select(i => new Customer { 
    result = i // telling LINQ to fill other properties as it is 
    IsVip = DetermineVip(i.Score) // then modifying this one property 
}).ToList(); 

Trả lời

2

bạn có thể sử dụng

return customers.Select(i => { 
    i.IsVip = DetermineVip(i.Score); 
    return i; 
}).ToList(); 
+0

Một lưu ý trước khi thực hiện việc này là bạn phải cẩn thận một chút. Ví dụ, nếu bạn làm 'customer.FullName + =" foo "' và bạn kết thúc liệt kê bộ sưu tập hai lần, bạn sẽ nhận được một số kết quả khá thú vị. –

1

Không, LINQ được thiết kế để lặp qua bộ sưu tập mà không ảnh hưởng đến nội dung của nguồn có thể đếm được.

Bạn tuy nhiên có thể tạo ra phương pháp riêng của mình để đi làm lại và biến đổi bộ sưu tập:

public static void ForEach<T>(this IEnumerable<T> enumeration, Action<T> action) 
{ 
    foreach(T item in enumeration) 
    { 
     action(item); 
    } 
} 

Sau đó bạn có thể sử dụng như sau:

return customers.ToList() 
       .ForEach(i => i.IsVip = DetermineVip(i.Score)) 
       .ToList(); 

Lưu ý rằng ForEach đầu tiên sẽ sao chép danh sách nguồn.

1

Bạn "có thể", nếu bạn tạo một constructor sao chép, mà khởi tạo một đối tượng mới với các giá trị của một đối tượng hiện có:

partial class Customer 
{ 
    public Customer(Customer original) 
    { 
     this.FullName = original.FullName; 
     //... 
    } 
} 

Sau đó, bạn có thể làm:

return customers.Select(i => new Customer(i) { IsVip = DetermineVip(i.Score)}) 
    .ToList() 

Nhưng sự sụp đổ ở đây là bạn sẽ được tạo đối tượng Customer mới dựa trên từng đối tượng hiện có và không sửa đổi đối tượng hiện tại - đây là lý do tại sao tôi đã đặt "có thể" trong dấu ngoặc kép. Tôi không biết nếu điều này thực sự là những gì bạn mong muốn.

0

Khi khách hàng đã là một danh sách, bạn có thể sử dụng phương pháp ForEach:

customers.ForEach(c => c.IsVip = DetermineVip(c.Score)); 
2

Trái ngược với câu trả lời khác, bạn có thể sửa đổi nội dung mã nguồn trong LINQ bằng cách gọi một phương thức trong câu lệnh Select (lưu ý rằng điều này không được EF hỗ trợ mặc dù đó không phải là vấn đề với bạn).

return customers.Select(customer => 
{ 
    customer.FullName = "foo"; 
    return customer; 
}); 
+0

Không chắc chắn, nhưng tôi cũng có một. Tuy nhiên, trước tiên bạn phải cẩn thận khi làm điều này. Ví dụ, nếu bạn làm 'customer.FullName + =" foo "' và bạn kết thúc liệt kê bộ sưu tập hai lần, bạn sẽ nhận được một số kết quả khá thú vị. –

+0

lc. có lẽ bạn đã nhầm lẫn 'khách hàng' đối với' khách hàng'. Giải pháp được cung cấp sẽ chỉ lặp lại bộ sưu tập một lần. – Polity

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