2009-08-21 2 views
0

동작이 발생했습니다. GridView를 채우려 고 할 때 꽤 이해할 수 없습니다. 다음 코드를 고려다른 개체가 수정 될 때 개체의 변수가 변경됩니다.

DataTable table = GetStockMovement((int)ViewState[MOVEMENT_ID], false); 
MovedProducts = from DataRow row in table.Rows 
        select new Product() 
        { 
         ProductId = (int)row["ProductId"], 
         ProductNo = row["ProductNo"].ToString(), 
         Name = row["ProductName"].ToString(), 
         Quantity = OriginalProducts.ToList().Find(p => p.ProductId == (int)row["ProductId"]).Quantity, 
         QuantityDiff = (int)row["Change"]                 
        }; 

foreach (Product product in MovedProducts) 
{ 
    Console.WriteLine(product.ProductId + ": " + product.Quantity); 
} 
Console.WriteLine(); 
foreach (Product product in OriginalProducts) 
{ 
    product.Quantity -= 1000; 
} 


foreach (Product product in MovedProducts) 
{ 
    Console.WriteLine(product.ProductId + ": " + product.Quantity); 
} 

이것의 출력은 다음과 같았다 :

1: 10 
2: 4 

1: -990 
2: -996 

Product.Quantity는 INT MovedProducts 및 OriginalProducts가 ViewState에 저장되어있는 IEnumerables이다.

원본 제품을 변경하면 MovedProducts의 제품이 변경되는 이유는 무엇입니까? 그것들은 완전히 다른 두 대상이 다른 장소에 저장되어 있지 않습니까?

I 대신에 사용되는 LINQ 표현하면

: 나는에 예상대로

List<FPRSProduct> completedProducts = new List<FPRSProduct>(); 
foreach (DataRow row in table.Rows) 
{ 
    Product tmp = new Product(); 
    tmp.ProductId = (int)row["ProductId"]; 
    tmp.ProductNo = row["ProductNo"].ToString(); 
    tmp.Name = row["ProductName"].ToString(); 
    tmp.Quantity = OriginalProducts.ToList().Find(p => p.ProductId == (int)row["ProductId"]).Quantity; 
    tmp.QuantityDiff = (int)row["Change"];                 
    completedProducts.Add(tmp); 
} 

모든 것이 잘되었다, 즉 내가 이전과 OriginalProducts의 수량을 변경 한 후 같은 번호를 얻을 수있다.

답변

2

LINQ는 지연 실행이라고하는 것을 사용합니다. linq 쿼리를 작성할 때 실제로 쿼리가 정의하는 작업을 수행하지 않고 ... 단순히 정의하는 것입니다. 귀하의 쿼리에 의해 정의 된 동작은 두 개의 foreach 문에서 귀하의 경우에 사용 순간에 실행됩니다. 쿼리는 각 foreach에 대해 두 번 실행되므로 데이터가 복사되지만 두 개의 다른 시점에서 소스에서 두 번 복사됩니다. MovedProducts 주변의 두 번째 foreach는 두 번째 foreach가 실제로 실행될 때까지 쿼리 실행이 연기되기 때문에 OriginalProducts에서 업데이트 된 데이터를 검색합니다.

주 당신의 연결 쿼리의 '선택'새로운 절에있는 코드의 주요 라인 :

Quantity = OriginalProducts.ToList().Find(p => p.ProductId == (int)row["ProductId"]).Quantity, 

것은 당신이 distinc를 만드는 경우에도, 새로운, 제 1 및 제 2의 foreach 사이 OriginalProducts를 업데이트하기 때문에 Product 객체 목록 ... 쿼리 처리가 지연되므로 각 제품에 대해 위의 행을 두 번 실행합니다. 첫번째 foreach를 위해 한 번, 그리고 두 번째 foreach를 위해 다시 한 번.

관련 문제