UpdateEntitiesDirectly and inherited entities

Posts   
 
    
jeffreygg
User
Posts: 805
Joined: 26-Oct-2003
# Posted on: 31-Oct-2008 00:56:46   

Hello, I'm upgrading old v1 code to 2.6 and running into the following issue.

I have a type called "Document" and a subtype called "PurchaseOrder". The following subroutine is intended to set the "IDDocumentStatus" field for all PurchaseOrders matching the IDs passed in.


    Public Sub ChangePOStatus(ByVal poIDsToChange As ArrayList, ByVal newDocumentStatusID As Guid) Implements IPurchaseOrderService.ChangePOStatus
        Dim adapter As DataAccessAdapter = GetAdapter()
        Dim poWithNewStatus As New PurchaseOrderEntity
        If newDocumentStatusID.Equals(Guid.Empty) Then
            poWithNewStatus.SetNewFieldValue(PurchaseOrderFieldIndex.IDDocumentStatus, Nothing)
        Else
            poWithNewStatus.IDDocumentStatus = newDocumentStatusID
        End If
        Dim predExp As New PredicateExpression(New FieldCompareRangePredicate(PurchaseOrderFields.IDPurchaseOrder, Nothing, poIDsToChange.ToArray(GetType(Guid))))
        adapter.UpdateEntitiesDirectly(poWithNewStatus, New RelationPredicateBucket(predExp))
    End Sub

Here's the resulting Sql:


UPDATE [dbo].[Document] 
SET [IDDocumentType]=@IDDocumentType,[IDDocumentStatus]=@IDDocumentStatus WHERE ( ( ( [dbo].[PurchaseOrder].[IDPurchaseOrder] IN (@IDPurchaseOrder1)))) 

The problem is that the Sql fails because dbo.PurchaseOrder isn't in the SELECT list. Since this is an inheritance hierarchy the Update statement looks like it's generated incorrectly, specifically there should be a JOIN to PurchaseOrder from Document.

This used to work in v1, but it seems something changed. Can anyone verify this for me?

Jeff...

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 31-Oct-2008 05:55:17   

Hi Jeff,

I don't know whether this changed. I encounter something on the change history, but I don't know it that change is referencing this situation.

As far as I know, you have to add a relation to the super type. Please try this:

Dim updateFilter As New RelationPredicateBucket(New FieldCompareRangePredicate(PurchaseOrderFields.IDPurchaseOrder, Nothing, poIDsToChange.ToArray(GetType(Guid))))

updateFilter.Relations.Add(PurchaseOrderEntity.Relations.GetSuperTypeRelation())

adapter.UpdateEntitiesDirectly(poWithNewStatus, updateFilter)
David Elizondo | LLBLGen Support Team
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39590
Joined: 17-Aug-2003
# Posted on: 31-Oct-2008 10:11:37   

No, don't add hierarchy relations directly, that should be unnecessary.

I'll look into it, as it looks like a bug.

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39590
Joined: 17-Aug-2003
# Posted on: 31-Oct-2008 10:26:02   

reproduced.



[Test]
public void UpdateSingleBoardmemberDirectlyThroughFilter()
{
    BoardMemberEntity newValues = new BoardMemberEntity();
    using(DataAccessAdapter adapter = new DataAccessAdapter())
    {
        EntityCollection toDelete = new EntityCollection();
        UnitOfWork2 uow = CreateTestBatchForSave2(ref toDelete);
        uow.Commit(adapter, true);

        // give all boardmembers a new startdate.
        DateTime newStartDate = DateTime.Now;
        newStartDate = newStartDate.AddMilliseconds(0 - newStartDate.Millisecond);
        newValues.StartDate = newStartDate;

        RelationPredicateBucket filter = new RelationPredicateBucket(BoardMemberFields.CompanyCarId==1);

        Assert.IsTrue((adapter.UpdateEntitiesDirectly(newValues, filter)> 0));
        Thread.Sleep(1000);
        EntityCollection allBoardMembers = new EntityCollection(new BoardMemberEntityFactory());
        // fetch all boardmembers and verify the updated date
        adapter.FetchEntityCollection(allBoardMembers, null);
        foreach(BoardMemberEntity boardMember in allBoardMembers)
        {
            // do a compare on date and hour/minute/second, as sqlserver rounds milliseconds so a full compare is not valid
            Assert.IsTrue((newStartDate.Date == boardMember.StartDate.Date) &&
                (newStartDate.Hour == boardMember.StartDate.Hour) &&
                (newStartDate.Minute == boardMember.StartDate.Minute) &&
                (newStartDate.Second == boardMember.StartDate.Second));
        }

        adapter.DeleteEntityCollection(toDelete);
    }
}

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39590
Joined: 17-Aug-2003
# Posted on: 31-Oct-2008 10:46:00   

Fixed in next build. See attached dll for the new build.

Frans Bouma | Lead developer LLBLGen Pro
jeffreygg
User
Posts: 805
Joined: 26-Oct-2003
# Posted on: 31-Oct-2008 17:44:43   

Thanks, Frans. simple_smile