2014-09-19 71 views
1

讓我們假設我有這個類的一個實例。C#在foreach循環中繼續處理對象的實例

public class MyClass 
{ 
    public string LocationCode; 
    public string PickUpCode 
} 

還有另外一個類,需要一個List<MyClass>作爲輸入並保存到數據庫。

現在我需要辦理一些業務規則:

例如,如果LocationCodenullList<MyClass>這個項目必須跳過,foreach循環必須continue到列表中的下一個項目。

我已經寫了下面的代碼,並與nullLocationCode的項目確實是跳過,但因此當循環達到一個有效的項目,並繼續將其保存在數據庫中var instance = new SomeClass();莫名其妙地保留在內存中,也保存所有以前跳過的實例var instance = new SomeClass();。這意味着我在數據庫中有空條目。

我正在使用NHibernateEvict沒有縫隙做的伎倆。有什麼建議麼?

public void Save(List<MyClass> listOfItems) 
{ 
    using (UnitOfWork.Start()) 
    { 
     var repository = new Repository(); 

     try 
     { 

      foreach (var item in listOfItems.Select(i => i.Item).Where(item => item != null)) 
      { 
       var instance = new SomeClass();   

       if (pickUpCode != null) 
       { 
        instance.PickUpCode = pickUpCode; 
       } 
       else 
       {    
        instance.PickUpCode = null; 
       } 

       if (locationCode != null) 
       { 
        instance.StartLocation = locationCode 
       } 
       else 
       { 
        UnitOfWork.CurrentSession.Evict(instance); 
        continue; 
       } 

       repository.SaveSomeClass(instance); 
      } 
     } 
     catch (Exception ex) 
     { 
      _log.Error(" Unhandled error", ex); 
     } 
    } 
} 

**因爲有人問,這裏的一對UnitOfWork.Start()

public static class UnitOfWork 
    {   
     public static IUnitOfWork Start(); 
    } 

public interface IUnitOfWork : IDisposable 
    { 
     bool IsInActiveTransaction { get; } 
     IUnitOfWorkFactory SessionFactory { get; } 

     IGenericTransaction BeginTransaction(); 
     IGenericTransaction BeginTransaction(IsolationLevel isolationLevel); 
     void Flush(); 
     void TransactionalFlush(); 
     void TransactionalFlush(IsolationLevel isolationLevel); 
    } 
+0

你沒有錯過'如果檢查添加到您LINQ(!item.pickUpCode = NULL)'和' if(item.locationCode!= null)'? – Michael 2014-09-19 07:26:00

+0

這是一個示例代碼。實際的更詳細。 – 2014-09-19 07:36:05

回答

2

爲什麼你不先失敗並避免所有這些?

的例子是:

foreach (var item in listOfItems.Select(i => i.Item).Where(item => item != null)) 
     { 

      if (item.LocationCode == null){ 
       continue; 
      } 

      var instance = new SomeClass();   

      if (pickUpCode != null) 
      { 
       instance.PickUpCode = pickUpCode; 
      } 
      else 
      {    
       instance.PickUpCode = null; 
      } 

      // if we reach here, location code is definitley not null, no need for the check    
      instance.StartLocation = locationCode 



      repository.SaveSomeClass(instance); 
     } 

或者,你可以在where子句

foreach (var item in listOfItems.where(item=> item != null && item.LocationCode != null) 
+1

與'UnitOfWork.CurrentSession.Clear();'命令的結合起到了訣竅的作用。非常感謝你! – 2014-09-19 09:16:16

+0

非常歡迎,我喜歡盡我所能幫忙 – 2014-09-19 09:54:16

0

一些代碼,而在UnitofWork.Start是如何工作的它很難提出更多的代碼。但是,值得嘗試在SomeClass上實現IDisposable。

+0

我也這麼想過。 – 2014-09-19 07:27:53

+0

對不起您的評論偏離。邁克爾摩爾的建議是正確的,但你將無法編譯。無論如何,是的,c#GC很好。我的預感是UnitOfWork.CurrentSession.Evict(instance);這個代碼,不知道這個黑盒子裏究竟發生了什麼,它仍然可以保存實例的引用。 – meetkichu 2014-09-19 07:36:06