Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework: Check all relationships of an entity for foreign key use

I have an entity, let's call it CommonEntity that has a primary key used as a foreign key in many other entities. As the application is developed these links will continue to grow.

I'd like a way to see if CommonEntity can be safely deleted (i.e. it's not used by any other entities).

I realise I can do

if(!ce.EntityA.Any() && !ce.EntityB.Any() ... && !ce.EntityN.Any())
{
   //Delete
}

but I'm hoping for a way to just check all of the relationships automatically, as I don't love the idea of having to come back and change this code manually every time we add a new relationship. Perhaps there is something in EF4+ that I'm not aware of?

I thought it might be possible to use a transaction scope to just try and delete the object and roll it back if it fails, but I wasn't sure if there were any adverse side effects with this approach.

Is there a better approach?

EDIT: Looks like VS2012 has used EF5 even though the project is .Net 4, so it has created the model with POCOs even though it was generated from a DB.

like image 246
BenC3 Avatar asked Oct 12 '12 01:10

BenC3


1 Answers

You can use Reflection for this (if you don't want use "Fail Delete On SQL") I write this because I dont want to DELETE Entity, just want to know if its related to any or not !

 public static object GetEntityFieldValue(this object entityObj, string propertyName)
        {
            var pro = entityObj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).First(x => x.Name == propertyName);
            return pro.GetValue(entityObj, null);

        }

 public static IEnumerable<PropertyInfo> GetManyRelatedEntityNavigatorProperties(object entityObj)
        {
            var props = entityObj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(x => x.CanWrite && x.GetGetMethod().IsVirtual && x.PropertyType.IsGenericType == true);
            return props;
        }

public static bool HasAnyRelation(object entityObj)
        {

                var collectionProps= GetManyRelatedEntityNavigatorProperties(entityObj);


                foreach (var item in collectionProps)
                {
                    var collectionValue = GetEntityFieldValue(entityObj,item.Name);
                    if (collectionValue != null && collectionValue is IEnumerable)
                    {
                        var col = collectionValue as IEnumerable;
                        if (col.GetEnumerator().MoveNext())
                        {
                            return true;
                        }

                    }
                }
               return false;
}

NOTE that : Context must not Disposed and Proxy Must Be Enabled AND KNOW THAT IT WILL GET ALL RELATED RECORD TO MEMORY (IT'S Too Heavy)

like image 85
mX64 Avatar answered Oct 04 '22 19:10

mX64