यह जाँचने का सबसे अच्छा तरीका है कि क्या वस्तु एंटिटी फ्रेमवर्क में मौजूद है?


114

प्रदर्शन के दृष्टिकोण से डेटाबेस में कोई वस्तु मौजूद है या नहीं यह जांचने का सबसे अच्छा तरीका क्या है? मैं एंटिटी फ्रेमवर्क 1.0 (ASP.NET 3.5 SP1) का उपयोग कर रहा हूं।

जवाबों:


228

यदि आप सीधे SQL निष्पादित नहीं करना चाहते हैं, तो सबसे अच्छा तरीका कोई भी () का उपयोग करना है । ऐसा इसलिए है क्योंकि कोई भी () मैच मिलते ही वापस आ जाएगा। एक अन्य विकल्प काउंट () है , लेकिन इसे लौटने से पहले हर पंक्ति को जांचना पड़ सकता है।

इसका उपयोग कैसे करें इसका एक उदाहरण यहां दिया गया है:

if (context.MyEntity.Any(o => o.Id == idToMatch))
{
    // Match!
}

और vb.net में

If context.MyEntity.Any(function(o) o.Id = idToMatch) Then
    ' Match!
End If

और VB में अगर (संदर्भ। MyEntity.Any (o => o.Id <> idToMAtch)) तो 'यह एक मैच है! अंत यदि क्षमा करें, यह कोड टैग में नहीं है, तो मैं यह नहीं पता लगा सकता कि यह कैसे करना है!
केविन मॉरिससी

आपको लगता है कि आपका मतलब o.Id है> idToMatch एक मैच के बराबर नहीं है
कॉलिन

क्या होगा अगर मैं नाम से खोजता हूं और अगर यह मौजूद है तो मैं आईडी प्राप्त करना चाहता हूं?
मिहाई ब्राटुल्स्कू

नमस्ते। अगर यह मौजूद है और उसके बाद इसके सभी डेटा का चयन कैसे कर सकते हैं?
पुण्योत्तर virt

1
@barnes यदि आप Tएक ऐसे इंटरफ़ेस के लिए विवश हैं जो IEnumerableऑब्जेक्ट है और जिसमें ए शामिल है Id, तो आपको अपने जेनेरिक फ़ंक्शन का उपयोग करने में सक्षम होना चाहिए IsExists<T>()
सनकैट २२

9

प्रदर्शन के दृष्टिकोण से, मुझे लगता है कि EXISTS कमांड का उपयोग करके एक सीधी SQL क्वेरी उचित होगी। SQL को सीधे एंटिटी फ्रेमवर्क में कैसे निष्पादित करें, इसके लिए यहां देखें: http://blogs.microsoft.co.il/blogs/gilf/archive/2009/11/25/execute-t-sql-statements-in-entity-framework- 4.aspx


हाँ, अच्छा विचार है, लेकिन इकाई ढांचे के पिछले संस्करण तक सीमित है।
फ्रेडी

5

मुझे एक परिदृश्य का प्रबंधन करना था जहां नए डेटा रिकॉर्ड में दिए जा रहे डुप्लिकेट का प्रतिशत बहुत अधिक था, और इसलिए डुप्लिकेट की जांच के लिए हजारों डेटाबेस कॉल किए जा रहे थे (इसलिए सीपीयू ने 100% पर बहुत समय भेजा)। अंत में मैंने स्मृति में कैश्ड पिछले 100,000 रिकॉर्ड रखने का फैसला किया। इस तरह मैं कैश्ड रिकॉर्ड के खिलाफ डुप्लिकेट की जांच कर सकता था जो कि SQL डेटाबेस के खिलाफ एक LINQ क्वेरी की तुलना में बेहद तेज था, और फिर डेटाबेस में किसी भी तरह से नए रिकॉर्ड लिख सकते हैं (साथ ही उन्हें डेटा कैश में जोड़ सकते हैं, जो कि मेरे पास भी है क्रमबद्ध और इसकी लंबाई प्रबंधनीय रखने के लिए छंटनी की गई)।

ध्यान दें कि कच्चा डेटा एक CSV फ़ाइल थी जिसमें कई व्यक्तिगत रिकॉर्ड होते थे जिन्हें पार्स किया जाना था। प्रत्येक लगातार फ़ाइल में रिकॉर्ड (जो लगभग हर 5 मिनट में 1 की दर से आया) बहुत अधिक ओवरलैप हो गया, इसलिए डुप्लिकेट का उच्च प्रतिशत।

संक्षेप में, यदि आपके पास कच्चा डेटा आ रहा है, तो क्रम में बहुत अधिक है, तो मेमोरी कैश का उपयोग करके रिकॉर्ड डुप्लिकेट जांच में मदद मिल सकती है।


2
कई बार जब हम डेवलपर्स आपके परिदृश्य के साथ आते हैं, तो कुछ ट्विस्ट के साथ हो सकते हैं। मैं आपसे C # में अपने समाधान का अनुवाद करने का अनुरोध करना चाहूंगा ताकि हम और आने वाले कई डेवलपर्स को फायदा हो। +1। मैं ब्लॉग पोस्ट तक विस्तारित समाधान को पसंद करूंगा! :)
sangam

3

मुझे पता है कि यह एक बहुत पुराना धागा है, लेकिन किसी को समझाइए कि मेरे जैसे व्यक्ति को इस समाधान की आवश्यकता है लेकिन ऊपर दिए गए उत्तरों के आधार पर VB.NET में यहाँ बताया गया है।

Private Function ValidateUniquePayroll(PropertyToCheck As String) As Boolean
    // Return true if Username is Unique
    Dim rtnValue = False
    Dim context = New CPMModel.CPMEntities
    If (context.Employees.Any()) Then ' Check if there are "any" records in the Employee table
        Dim employee = From c In context.Employees Select c.PayrollNumber ' Select just the PayrollNumber column to work with
        For Each item As Object In employee ' Loop through each employee in the Employees entity
            If (item = PropertyToCheck) Then ' Check if PayrollNumber in current row matches PropertyToCheck
                // Found a match, throw exception and return False
                rtnValue = False
                Exit For
            Else
                // No matches, return True (Unique)
                rtnValue = True
            End If
        Next
    Else
        // The is currently no employees in the person entity so return True (Unqiue)
        rtnValue = True
    End If
    Return rtnValue
End Function

मुझे नहीं पता कि वीबी में लैंबडा का उपयोग कैसे किया जाता है, लेकिन सी # में यह समतुल्य है: संदर्भ! संदर्भ। कर्मचारी। कोई (सी => सी। पेरोलनंबर == प्रॉपर्टीटचेक)। यह सभी परिणामों को फिर से याद करने से बचता है।
कॉलिन

1
@ कोलिन यह एक अच्छा जोड़ है मैंने उपरोक्त कोड के साथ मेमोरी मुद्दे की अनदेखी की, वीबी में कोड संदर्भ है। इम्प्लॉइज। कोई (c => c.PayrollNumber <> PropertyToCheck)। मैंने अब इसे अपने कोड में जोड़ दिया है।
केविन मॉरिससी

केविन, मुझे लगता है कि आपको वापस जाना होगा और अपना कोड ठीक करना होगा। अगर कोई मेल खाते हुए पेरोल नंबर नहीं हैं, तो आपके तर्क निश्चित रूप से सही लौट रहे हैं, जो मेल खाने के बजाय मेल खाते हैं।
कॉलिन

@Colin क्षमा करें आप सही हैं, मैं आपके उदाहरण के लिए एक VB संस्करण प्रदान कर रहा था केवल मैं ज्यादा C # सही नहीं सोचता था और इसलिए मेरे VB <> के बराबर नहीं था।
केविन मॉरिससी ने

1
@KevinMorrissey मुझे लगता है कि कॉलिंग कह रहा था कि आपको "संदर्भ" के सामने "नहीं" डालने की आवश्यकता है। के बाद से "वापस नहीं context.Employees.Any (ग => c.PayrollNumber = PropertyToCheck)" नहीं है (मैं फिर कहता हूँ), है नहीं के रूप में ही "वापस context.Employees.Any (ग <> c.PayrollNumber = PropertyToCheck)" । क्या आपको मेरी बात दिखती हैं? "रिटर्न एनी <>" का उपयोग करने का मतलब है कि अगर आपको ऐसा कोई भी मिलता है जो इस नंबर से मेल नहीं खाता है (भले ही कोई मिलान मौजूद हो), कोई भी बात सही नहीं होगी। इसके बजाय, "नहीं [...] का उपयोग करते हुए। कोई भी =" केवल तभी वापस लौटेगा जब वह उस पंक्ति को नहीं खोज सकता जिसे आप खोज रहे हैं! आपको फर्क दिखता हैं?
Erx_VB.NExT.Coder

2

मुझे इससे कुछ परेशानी थी - मेरे एंटिटीके में तीन गुण हैं (3 कॉलम के साथ पीके) और मैं प्रत्येक कॉलम की जांच नहीं करना चाहता था क्योंकि यह बदसूरत होगा। मैंने एक समाधान के बारे में सोचा जो सभी संस्थाओं के साथ हर समय काम करता है।

इसका एक और कारण है कि मैं हर बार UpdateException को पकड़ना पसंद नहीं करता।

प्रमुख गुणों के मूल्यों को प्राप्त करने के लिए थोड़ा सा परावर्तन आवश्यक है।

उपयोग को सरल बनाने के लिए कोड को विस्तार के रूप में लागू किया जाता है:

context.EntityExists<MyEntityType>(item);

एक नज़र देख लो:

public static bool EntityExists<T>(this ObjectContext context, T entity)
        where T : EntityObject
    {
        object value;
        var entityKeyValues = new List<KeyValuePair<string, object>>();
        var objectSet = context.CreateObjectSet<T>().EntitySet;
        foreach (var member in objectSet.ElementType.KeyMembers)
        {
            var info = entity.GetType().GetProperty(member.Name);
            var tempValue = info.GetValue(entity, null);
            var pair = new KeyValuePair<string, object>(member.Name, tempValue);
            entityKeyValues.Add(pair);
        }
        var key = new EntityKey(objectSet.EntityContainer.Name + "." + objectSet.Name, entityKeyValues);
        if (context.TryGetObjectByKey(key, out value))
        {
            return value != null;
        }
        return false;
    }

1
मैं अपने उत्तर में एक टिप्पणी जोड़ना चाहूंगा जो अब लगभग 9 वर्ष की है। मुझे लगता है कि आजकल बहुत सारे सॉल्यूशन सॉल्यूशंस और संभावनाएं हैं। 2010/2011 में एंटिटी फ्रैमवर्क 4 के साथ थे। इसलिए मैं इस जवाब को वोट करने से रोकने की सलाह दूंगा, लेकिन इसके बजाय नीचे एक नया / बेहतर जवाब जोड़ें।
स्वेन

कृपया यह भी ध्यान रखें कि मेरा समाधान एक सामान्य था जो मौजूदा तालिकाओं की कुल कुंजियों के साथ कई संस्थाओं के लिए काम करता था / जो मैं नहीं बदल सकता था। इसलिए हमेशा क्वैरी करने के बजाय .Any (...) 3 मुख्य गुणों के साथ जिन्हें मैंने केवल कॉल किया है .EntityExists ()।
स्वेन

2

मैं बस जाँचता हूं कि क्या वस्तु अशक्त है, यह मेरे लिए 100% काम करता है

    try
    {
        var ID = Convert.ToInt32(Request.Params["ID"]);
        var Cert = (from cert in db.TblCompCertUploads where cert.CertID == ID select cert).FirstOrDefault();
        if (Cert != null)
        {
            db.TblCompCertUploads.DeleteObject(Cert);
            db.SaveChanges();
            ViewBag.Msg = "Deleted Successfully";
        }
        else
        {
            ViewBag.Msg = "Not Found !!";
        }                           
    }
    catch
    {
        ViewBag.Msg = "Something Went wrong";
    }

0

क्यों नहीं करते?

var result= ctx.table.Where(x => x.UserName == "Value").FirstOrDefault();

if(result?.field == value)
{
  // Match!
}

यह एक अशक्त संदर्भ अपवाद को फेंक देगा क्योंकि FirstOrDefault () यदि परिणाम नहीं मिल रहा है तो अशक्त वापस आ जाएगा। मुझे लगता है कि आप (परिणाम? .Field == मूल्य) से बचने के लिए कर सकते हैं।
ToDevAndBeyond

यह अनावश्यक रूप से धीमा हो सकता है क्योंकि यह इकाई को लोड करता है। यदि आप सब करना चाहते हैं कि एक कुंजी मौजूद है या नहीं की जाँच करें।
डगलस गास्केल

0

इसे करने का सबसे अच्छा तरीका है

भले ही आपकी वस्तु क्या हो और डेटाबेस में किस तालिका के लिए केवल वही चीज होनी चाहिए जो वस्तु में प्राथमिक कुंजी है।

C # कोड

var dbValue = EntityObject.Entry(obj).GetDatabaseValues();
if (dbValue == null)
{
   Don't exist
}

VB.NET कोड

Dim dbValue = EntityObject.Entry(obj).GetDatabaseValues()
If dbValue Is Nothing Then
   Don't exist
End If

दो लगभग समान जवाब क्यों? अंतर नगण्य है। इसके अलावा, यह निश्चित रूप से ऐसा करने का सबसे अच्छा तरीका नहीं है। इसका कोई मतलब नहीं है कि अल वैल्यू को खींचने के लिए डेटाबेस की जाँच करें कि क्या कोई रिकॉर्ड मौजूद है
गर्ट अर्नोल्ड
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.