2012-10-12 17 views
8

मेरे पास एक इकाई है, चलो इसे CommonEntity पर कॉल करें जिसमें कई अन्य इकाइयों में एक विदेशी कुंजी के रूप में उपयोग की जाने वाली प्राथमिक कुंजी है। चूंकि आवेदन विकसित किया गया है, ये लिंक बढ़ते रहेंगे।इकाई फ्रेमवर्क: विदेशी कुंजी उपयोग के लिए किसी इकाई के सभी रिश्तों की जांच करें

मुझे यह देखने का एक तरीका चाहिए कि CommonEntity सुरक्षित रूप से हटाया जा सकता है (यानी यह किसी अन्य संस्था द्वारा उपयोग नहीं किया जाता है)।

मुझे पता है मैं

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

कर सकते हैं, लेकिन मैं एक तरह से स्वचालित रूप से संबंधों के सभी की जाँच करने के लिए आशा करती हूं कि, जैसा कि मैंने वापस आने के लिए करने का विचार प्यार नहीं करते और इस कोड को परिवर्तित मैन्युअल रूप से हर बार जब हम एक नया रिश्ता जोड़ते हैं। शायद ईएफ 4 + में कुछ ऐसा है जो मुझे पता नहीं है?

मैंने सोचा कि ऑब्जेक्ट को बस कोशिश करने और हटाने के लिए लेनदेन के दायरे का उपयोग करना संभव हो सकता है और अगर यह विफल हो जाता है तो इसे वापस रोल करें, लेकिन मुझे यकीन नहीं था कि इस दृष्टिकोण के साथ कोई प्रतिकूल दुष्प्रभाव हैं या नहीं।

क्या कोई बेहतर तरीका है?

संपादित करें: लगता VS2012 तरह EF5 इस्तेमाल किया गया है, भले ही परियोजना नेट 4 है, इसलिए यह Pocos साथ मॉडल हालांकि यह एक डीबी से बनाया गया था बनाया गया है।

उत्तर

8

बस इसे विफल करते हैं। अगर इकाई के कई रिश्तों हैं, तो वह सत्यापन वास्तव में भारी हो सकता है।

public bool TryDelete(int id) 
{ 
    try 
    { 
     // Delete 
     return true; 
    } 
    catch (SqlException ex) 
    { 
     if (ex.Number == 547) return false; // The {...} statement conflicted with the {...} constraint {...} 
     throw; // other error 
    } 
} 
+0

यदि मैं इसे असफल होने देता हूं, तो क्या यह स्वचालित रूप से लेनदेन के दायरे के बिना किसी भी सफल कैस्केडिंग को वापस लाएगा? – BenC3

+1

उत्तर मिला - SaveChanges() एक लेनदेन का उपयोग करता है, इसलिए किसी भी विफलता को वापस ले जाया जाएगा: http://msdn.microsoft.com/en-us/library/bb336792.aspx – BenC3

+0

यदि आप अपनी संस्थाओं को खुले रखते हैं तो बिल्कुल अच्छा नहीं है ! – bytecode77

4

आप इस कोशिश कर सकते हैं:

var allrelatedEnds = ((IEntityWithRelationships)ce).RelationshipManager.GetAllRelatedEnds(); 
bool hasRelation = false; 
foreach (var relatedEnd in allrelatedEnds) 
{ 
    if (relatedEnd.GetEnumerator().MoveNext()) 
    { 
     hasRelation = true; 
     break; 
    } 
} 

if (!hasRelation) 
{ 
    //Delete 
} 
+0

कुछ शोध करने के बाद ऐसा लगता है कि वीएस 2 012 .NET 4 को लक्षित करते समय भी EF5 के संस्करण का उपयोग करता है, इतनी लंबी कहानी है कि यह मेरे लिए जेओसी उत्पन्न करता है, भले ही मैंने डीबी से मॉडल जेनरेट किया हो, इसलिए मैं 'आईएनटीटीआईथ रिलेशनशिप' पर नहीं डाल सकता। इसका उल्लेख करने के लिए मेरा बुरा! – BenC3

2

आप इस के लिए प्रतिबिंब का उपयोग कर सकते हैं (यदि आप उपयोग "असफल हटाएँ एसक्यूएल पर" नहीं करना चाहती) मैं यह लिख क्योंकि मैं इकाई को नष्ट करना चाहते नहीं है, सिर्फ अगर करने के लिए इससे संबंधित जानना चाहते हैं किसी भी या नहीं !

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

नोट है कि: प्रसंग निपटाई गई और प्रॉक्सी नहीं सक्षम किया जाना चाहिए चाहिए और पता है कि यह (यह भी हेवी)

+1

यह मेरा वास्तव में अच्छा तरीका है, मुझे लगता है कि 'MyClass.Any() || MyOtherClass.Any() 'आदि आदि एक बात मैं जोड़ा एक()) आप' HasAnyRelation में 'Property' शामिल नहीं करने का फैसला करने के लिए अनुमति देने के लिए विशेषता अनदेखा किया गया था' ' GetManyRelatedEntityNavigatorProperties (' इस तरह दिखता है ... 'var props = entityObj।GetType()। GetProperties (BindingFlags.Public | BindingFlags.Instance)। जहां (x => x.CanWrite && x.GetGetMethod()। IsVirtual && x.PropertyType.IsGenericType &&(x.GetCustomAttribute (typeof (IgnoreIsDeletableAttribute)) == शून्य) ); ' – Gwasshoppa

0

प्रथम इकाई है जो आप का उपयोग कर नष्ट करना चाहते हैं लगता है याद करने के लिए सभी संबंधित रिकॉर्ड प्राप्त होगा ईएफ में खोजें और नीचे कार्य करने के लिए इकाई को पास करें .. यदि फ़ंक्शन सत्य लौटाता है तो इसका मतलब है कि हटाया नहीं जा सकता है और विदेशी डेटा मौजूद है .. यदि फ़ंक्शन गलत होता है तो इसका मतलब है कि कोई माता-पिता या बाल रिकॉर्ड नहीं है और इसे हटाया जा सकता है ..

public static bool DeleteCheckOnEntity(object entity) 
    { 
    var propertiesList = entity.GetType().GetProperties(); 
    return (from prop in propertiesList where prop.PropertyType.IsGenericType select prop.GetValue(entity) into propValue select propValue as IList).All(propList => propList == null || propList.Count <= 0); 
    } 
संबंधित मुद्दे