简体   繁体   中英

C# handle instance of an object after continue in foreach loop

Let's assume I have an instance of this class.

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

There is another class that takes a List<MyClass> as input and saves to the DB.

Now I need to apply some business rules:

For example if LocationCode is null this item in the List<MyClass> must be skipped and the foreach loop must continue to the next item in the list.

I've written the following code and the items with null LocationCode are indeed skipped but the var instance = new SomeClass(); somehow remains in memory so when the loop reaches an valid item and proceeds to save it in the DB, it also saves all the previously skipped instances of var instance = new SomeClass(); . Which means I have null entries in the DB.

I'm using NHibernate and Evict doesn't seam to be doing the trick. Any suggestions?

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);
        }
    }
}

** Because someone asked, here's some code on 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);
    }

Why don't you fail first and avoid all of this?

Example being:

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);
        }

Alternatively, you could add the check to you LINQ where clause

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

Without more code on how UnitofWork.Start works its hard to suggest. But, It's worth trying by implementing IDisposable on SomeClass.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM