Check Related Entities Before Deleting

Posts   
 
    
Bashar
User
Posts: 108
Joined: 11-Nov-2004
# Posted on: 13-Apr-2010 11:46:36   

Hello,

I have an 'Accounts' table that is related to 16 other tables. Before deleting an 'account' I want to check the 16 other tables and see if this account is used in any of the other tables.

I know there are a gazillion ways to do this, ranging from writing specific code for each related table to firing a specific error and handling it, however, I would like to see if this can be achieved using any/all of the following functions:

  • GetRelatedData
  • GetDependingRelatedEntities
  • GetDependentRelatedEntities
  • GetMemberEntityCollections The rule is to see if account number '11001', for example, is used in any of the related tables and if possible how many times.

Can this be achieved?

Thanks, Bashar

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 13-Apr-2010 12:12:47   

GetDependant and DependingRelatedEntities, works on related entities in memory, so if you haven't fecthed or prefetched these entities, these methods won't help you.

I suggest you issue a scalar query for each related table, to return the Count(*) of rows, with a filter on the AccountId.

A side question: what will you do if you discover that there are related entities that refers to this Account? Will you cancel the delete operation or Delete the related records first then delete the Account afterwards.

Bashar
User
Posts: 108
Joined: 11-Nov-2004
# Posted on: 13-Apr-2010 12:47:18   

Thank you Walaa, but what I'm trying to do is have a sort of generic function to do this. I don't want to have to write a separate query for each related table; which is what I used to do.

If there are related entities, I'll probably let the user know and then cancel the whole process.

What do you think?

Bashar
User
Posts: 108
Joined: 11-Nov-2004
# Posted on: 13-Apr-2010 12:50:14   

Here is what I used to do:

Partial Class frmAccountList

    Public Shared Function GetRelatedJournalDetailCount(ByVal accountId As String) As Long

        Dim ec As New JournalDetailCollection

        Dim filter As IPredicateExpression = New PredicateExpression
        filter.Add(JournalDetailFields.StrAccountId = accountId)

        Dim relations As IRelationCollection = New RelationCollection
        relations.Add(AccountEntity.Relations.JournalDetailEntityUsingStrAccountId)

        Return CLng(ec.GetDbCount(filter, relations))

    End Function

    Public Shared Function GetRelatedIssueDetailCount(ByVal accountId As String) As Long

        Dim ec As New JournalDetailCollection

        Dim filter As IPredicateExpression = New PredicateExpression
        filter.Add(JournalDetailFields.StrAccountId = accountId)

        Dim relations As IRelationCollection = New RelationCollection
        relations.Add(AccountEntity.Relations.JournalDetailEntityUsingStrAccountId)

        Return CLng(ec.GetDbCount(filter, relations))

    End Function

End Class

I want to move away from this repetitious work simple_smile

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 13-Apr-2010 14:07:09   

The following is some code you can start with:

        private void SomeMethod(IEntity entity)
        {
            var relations = entity.GetAllRelations();   

            foreach (var relation in relations)
            {
                if(relation.StartElementIsPkSide)
                {
                    var fieldCore = relation.GetFKEntityFieldCore(0);
                    var entityName = fieldCore.ContainingObjectName;
                }
            }
        }

Passing an entity, you can get hold of the related dependant entityName, then you can use reflection to get an instance of that entity or collection.

Bashar
User
Posts: 108
Joined: 11-Nov-2004
# Posted on: 13-Apr-2010 21:04:58   

Thanks Walla smile I'll try it and see.

Bashar
User
Posts: 108
Joined: 11-Nov-2004
# Posted on: 13-Apr-2010 22:20:32   

Here's the code I wrote. It works fine.

Dim x As AccountEntity = Me.CurrentEntity
        Dim relations = x.GetAllRelations

        For Each r In relations
            If r.StartElementIsPkSide Then
                Dim fc As IEntityFieldCore = r.GetFKEntityFieldCore(0)
                Dim en As String = fc.ContainingObjectName

                Dim typeOfEntity As EntityType = DirectCast([Enum].Parse(GetType(EntityType), en, False), EntityType)
                Dim entityInstance As IEntity = FactoryClasses.GeneralEntityFactory.Create(typeOfEntity)
                Dim ec As IEntityCollection = entityInstance.GetEntityFactory.CreateEntityCollection()

                Dim bucket As IPredicateExpression = New PredicateExpression
                bucket.Add(New FieldCompareValuePredicate(DirectCast(fc, IEntityField), ComparisonOperator.Equal, x.StrAccountId))

                Dim rs As IRelationCollection = New RelationCollection
                rs.Add(r)

                Dim c As Long = Convert.ToInt64(ec.GetDbCount(bucket, rs))
                If c > 0 Then
                    Utils.ShowMsg(String.Format("Related entities: {0}", en))
                    Return
                End If
            End If
        Next
daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 14-Apr-2010 04:00:36   

Thanks for sharing Bashar.

David Elizondo | LLBLGen Support Team