2013-08-27 4 views
0

다음 코드 예제를 살펴보십시오.저장시 부모에게 컬렉션 속성이 제대로 추가되지 않습니다.

가 무엇을 :

  1. 반복 해 고객의 무리. 고객을 이미 알고있는 경우 해당 고객의 기존 데이터베이스 오브젝트를 검색합니다 (이는 문제가있는 부분입니다). 그렇지 않으면, 새로운 객체를 생성합니다 (이것은 잘 동작합니다).
  2. 사회 보장 번호 (CPR)가 일치하는 모든 대출이 신규 또는 기존 고객에게 추가됩니다.

문제점 : 새로운 고객 오브젝트에 대해 작동하지만 기존 고객 오브젝트를 검색 할 때 대출은 고객 (CustomerID = null)과 관련하여 고객과의 관계를 상실합니다. 그것들은 여전히 ​​데이터베이스에 저장됩니다.

아이디어가 있으십니까?

protected void BuildCustomerData() 
{ 
    Console.WriteLine(" Starting the customer build."); 

    var counter = 0; 
    var recycleCount = 100; 
    var reportingCount = 100; 

    var sTime = DateTime.Now; 

    var q = from c in db.IntermediaryRkos 
      select c.CPR; 

    var distincts = q.Distinct().ToArray(); 
    var numbersToProcess = distincts.Count(); 

    Console.WriteLine(" Identified " + numbersToProcess + " customers. " + (DateTime.Now - sTime).TotalSeconds); 

    foreach (var item in distincts) 
    { 
     var loans = from c in db.IntermediaryRkos 
        where c.CPR == item 
        select c; 

     var existing = db.Customers.Where(x => x.CPR == item).FirstOrDefault(); 

     if (existing != null) 
     { 
      this.GenerateLoanListFor(existing, loans); 
      db.Entry(existing).State = System.Data.EntityState.Modified; 
     } 
     else 
     { 
      var customer = new Customer 
      { 
       CPR = item, 
      }; 

      this.GenerateLoanListFor(customer, loans); 
      db.Customers.Add(customer); 
      db.Entry(customer).State = System.Data.EntityState.Added; 
     } 

     counter++; 

     if (counter % recycleCount == 0) 
     { 
      this.SaveAndRecycleContext(); 
     } 

     if (counter % reportingCount == 0) 
     { 
      Console.WriteLine(" Processed " + counter + " customers of " + numbersToProcess + "."); 
     } 
    } 

    db.SaveChanges(); 
} 

protected void GenerateLoanListFor(Customer customer, IQueryable<IntermediaryRko> loans) 
{ 
    customer.Loans = new List<Loan>(); 

    foreach (var item in loans.Where(x => x.DebtPrefix == "SomeCategory").ToList()) 
    { 
     var transformed = StudentLoanMap.CreateFrom(item); 

     customer.Loans.Add(transformed); 

     db.Entry(transformed).State = System.Data.EntityState.Added; 
    } 
} 

편집 1 : 지적

, 나는 수동으로 상태를 설정하고있다. 이것은 최대 DB 트랜잭션 성능을 구현하는 RecycleContext 호출로 인해 :

protected void SaveAndRecycleContext() 
{ 
    db.SaveChanges(); 
    db.Dispose(); 
    db = new SolutionDatabase(); 
    db.Configuration.AutoDetectChangesEnabled = false; 
    db.Configuration.ValidateOnSaveEnabled = false; 
} 
+0

'를 호출 할 때 customer.Loans 속성을 닦아 d는 db 재사용 문제가 uses 절 및 범위 관리에 의해 더 잘 관리 될 수 있다고 생각합니다. – Maslow

+0

팁은 좋지만 현재 문제는 해결되지 않습니다. –

+0

AutoDetectChangesEnabled 및 ValidateOnSaveEnabled를 다시 사용하면 원래 문제는 해결되지만 받아 들일 수없는 매우 큰 성능 문제가 발생합니다. 그것은 이미 약 1 시간을 요구하는 예쁜 작업입니다. 이러한 기능을 사용하면 약 4-5 시간이 걸립니다. –

답변

0

기존 대출 여부, 당신은 당신이 내가

customer.Loans = new List<Loan>();

+0

참. 나는 그 라인의 유무에 관계없이 노력했다. 문제가되지 않는다. 그러나 매번 대출 데이터를 갱신해야하므로 매번 목록을 지우는 것이 좋습니다. –

+0

당신은 또한'.State' 속성을 수동으로 조작하는 대신에, 각각에 대해 옳다고 생각하는 것을 사용하도록합니다. – Maslow

+0

다시 한번 진실입니다. 편집 설명 1. –

관련 문제