DataScope with new entity possible?

Posts   
 
    
Puser
User
Posts: 228
Joined: 20-Sep-2012
# Posted on: 29-Mar-2016 12:05:58   

I'm using LLBLGen Pro v4.2 Final (March 10th, 2016) and work with Adapter.

I was under the impression that I could add Newly created Entities to a DataScope, update these and then save these with a CommitChanges. But Commitchanges only returns false without any information. Maybe this is not the purpose for a DataScope, but I want to be able to have the same experience with a new Entity as with an existing entity when dealing with updates, child entity additions/updates. Otherwise I think I need a UnitOfWork2 and then I have to implement all good stuff of DataScope myself (for each different UoW). Is there an option I forgot or another pattern/way to implement this?

Puser
User
Posts: 228
Joined: 20-Sep-2012
# Posted on: 29-Mar-2016 16:03:38   

After testing a bit further, I fetched a persisted entity (of the same type) and attached it to the DataScope. Then all new entities were saved! But without this dirty or 'clean' entity the DataScope does not Commit any changes.

What could this be? The generated target platform is 4.6 using adapter.

Code:


        public ValidationSummary Save(IEnumerable<VerkoopFaktuurDto> dtos)
        {
            var f2 = _verkoopFaktuurRepository.GetAggregateById(1); //this gets a persisted entity
            //f2.Bedrag = 130; //To check dirty or not dirty effect
            _unitOfWork.Add(f2); //type is VerkoopFaktuurUnitOfWork
            var validation = new ValidationSummary();
            var fakturen = new EntityCollection<FaktuurEntity>();
            foreach (var dto in dtos)
            {
                var faktuur = VerkoopFaktuurFactory.CreateVerkoopFaktuur();
                fakturen.Add(faktuur);

                _mapper.MapFromDto(faktuur, dto);
                ApplyBusinessLogic(faktuur);

                var results = _validator.Validate(faktuur);
                if (results.IsValid)
                    _unitOfWork.Add(faktuur);
                else
                    validation.Add(SeverityLevel.Critical, LogLevel.Event, null, results.Errors.ToString(","));
            }
            var isSaved = _unitOfWork.CommitChanges();
            return validation;
        }

---

    public class VerkoopFaktuurUnitOfWork : DataScope
    {
        private readonly IDataAccessAdapterFactorySales _adapterFactory;

        public VerkoopFaktuurUnitOfWork(IDataAccessAdapterFactorySales adapterFactory)
        {
            _adapterFactory = adapterFactory;
            base.RefetchStrategy = DataScopeRefetchStrategyType.DoNothing;
        }

        public void Add(FaktuurEntity entity)
        {
            Attach(entity);
        }

        public void Add(EntityCollection<FaktuurEntity> entities)
        {
            Attach(entities);
        }

        public bool CommitChanges()
        {
            using (var adapter = _adapterFactory.CreateDataAccessAdapter())
            {
                return base.CommitChanges(adapter);
            }
        }

        protected override bool FetchDataImpl(params object[] fetchMethodParameters)
        {
            throw new NotImplementedException();
        }
Walaa avatar
Walaa
Support Team
Posts: 14946
Joined: 21-Aug-2005
# Posted on: 29-Mar-2016 20:30:04   

Reporduced.

var cust = new CustomerEntity();
cust.CustomerId = "NEW01";
cust.CompanyName = "NEW_Company";
_customerScope.Add(cust);
_customerScope.CommitChanges(new DataAccessAdapter());
Puser
User
Posts: 228
Joined: 20-Sep-2012
# Posted on: 30-Mar-2016 11:49:43   

Thank you Walaa,

is there something I can do to fix it?

best regards

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39588
Joined: 17-Aug-2003
# Posted on: 30-Mar-2016 14:15:20   

I'll look into this shortly (within the hour)

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39588
Joined: 17-Aug-2003
# Posted on: 30-Mar-2016 14:43:39   

My tests succeed


[Test]
public void InsertTest()
{
    var scope = new UpdateInsertDataScope(10254);
    scope.FetchData();

    var newOrderDetail = new OrderDetailsEntity();
    newOrderDetail.ProductId = 1;
    newOrderDetail.OrderId = scope.Order.OrderId;
    newOrderDetail.Quantity = (short)10;
    newOrderDetail.Discount = 0.0f;
    newOrderDetail.UnitPrice = 10.2M;
    scope.Add(newOrderDetail);
            
    UnitOfWork2 uow = null;
    Func<IUnitOfWorkCore, bool> commitFunc = a => { uow = (UnitOfWork2)a; return true; };
    scope.CommitChanges(commitFunc);
    uow.ConstructSaveProcessQueues();
    var insertQueue = uow.GetInsertQueue();
    var updateQueue = uow.GetUpdateQueue();
    Assert.AreEqual(1, insertQueue.Count);
    Assert.AreEqual(0, updateQueue.Count);
    Assert.AreEqual(newOrderDetail, insertQueue.First().Entity);
}

So there's something else going on... looking into your specific code.

(edit). Is your scope entirely empty before you add the new entity and commit the changes?

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39588
Joined: 17-Aug-2003
# Posted on: 30-Mar-2016 14:49:10   

Never mind, if I don't fetch any data, so the scope is completely empty it fails.

[Test]
public void InsertTest()
{
    var scope = new UpdateInsertDataScope(10254);
    var newOrderDetail = new OrderDetailsEntity();
    newOrderDetail.ProductId = 1;
    newOrderDetail.OrderId = 10254;
    newOrderDetail.Quantity = (short)10;
    newOrderDetail.Discount = 0.0f;
    newOrderDetail.UnitPrice = 10.2M;
    scope.Add(newOrderDetail);
            
    UnitOfWork2 uow = null;
    Func<IUnitOfWorkCore, bool> commitFunc = a => { uow = (UnitOfWork2)a; return true; };
    scope.CommitChanges(commitFunc);
    uow.ConstructSaveProcessQueues();
    var insertQueue = uow.GetInsertQueue();
    var updateQueue = uow.GetUpdateQueue();
    Assert.AreEqual(1, insertQueue.Count);
    Assert.AreEqual(0, updateQueue.Count);
    Assert.AreEqual(newOrderDetail, insertQueue.First().Entity);
}

Looking into it.

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39588
Joined: 17-Aug-2003
# Posted on: 30-Mar-2016 14:53:58   

Bug, looking into fixing it.

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39588
Joined: 17-Aug-2003
# Posted on: 30-Mar-2016 15:25:31   

Fixed. See attached release build.

The main problem was that 'new' entities don't have a hashcode so they weren't really part of the hashsets for entities and it checked that set to see which type of UoW class it should create. As it saw no entity, it returned the no-op UoW. The fix now properly checks whether there are new entities as well, and it will make sure it will return a proper UoW based on that.

Attachments
Filename File size Added on Approval
ORMSupportClasses_42_20160330.zip 950,420 30-Mar-2016 15:25.39 Approved
Frans Bouma | Lead developer LLBLGen Pro
Puser
User
Posts: 228
Joined: 20-Sep-2012
# Posted on: 30-Mar-2016 20:34:38   

Wow Frans, fast fix! Thank you.

I will check this first thing tomorrow.

Puser
User
Posts: 228
Joined: 20-Sep-2012
# Posted on: 30-Mar-2016 20:41:33   

It works simple_smile