रिपॉजिटरी पैटर्न का उपयोग नहीं करते हुए, ORM का उपयोग करें (EF)


95

मैंने हमेशा रिपॉजिटरी पैटर्न का उपयोग किया लेकिन अपनी नवीनतम परियोजना के लिए मैं यह देखना चाहता था कि क्या मैं इसका उपयोग कर सकता हूं और "यूनिट ऑफ़ वर्क" को लागू कर सकता हूं। जितना मैंने खुदाई शुरू की मैंने खुद से सवाल पूछना शुरू कर दिया: "क्या मुझे वास्तव में इसकी आवश्यकता है?"

अब यह सब स्टैकओवरफ़्लो पर टिप्पणी के एक जोड़े के साथ शुरू होता है, जिसमें आयेंद रहियन की पोस्ट पर 2% के साथ एक ट्रेस है,

यह शायद हमेशा और हमेशा के लिए बात की जा सकती है और यह विभिन्न अनुप्रयोगों पर निर्भर करता है। मुझे जानना अच्छा लगता है,

  1. क्या यह दृष्टिकोण एंटिटी फ्रेमवर्क परियोजना के लिए अनुकूल होगा?
  2. इस दृष्टिकोण का उपयोग करना व्यवसाय तर्क अभी भी एक सेवा परत, या विस्तार विधियों में जा रहा है (जैसा कि नीचे बताया गया है, मुझे पता है, विस्तार विधि NHib सत्र का उपयोग कर रही है)?

यह विस्तार विधियों का उपयोग करके आसानी से किया जाता है। स्वच्छ, सरल और पुन: प्रयोज्य।

public static IEnumerable GetAll(
    this ISession instance, Expression<Func<T, bool>> where) where T : class
{
    return instance.QueryOver().Where(where).List();
}

इस दृष्टिकोण का उपयोग करते हुए और NinjectDI के रूप में, क्या मुझे Contextएक इंटरफ़ेस बनाने और अपने नियंत्रकों में इंजेक्ट करने की आवश्यकता है?

जवाबों:


103

मैंने कई रास्तों को छोड़ दिया है और विभिन्न परियोजनाओं पर रिपॉजिटरी के कई कार्यान्वयन बनाए हैं और ... मैंने तौलिया को अंदर फेंक दिया है और इसे छोड़ दिया है, यहां बताया गया है।

अपवाद के लिए कोडिंग

क्या आप उस 1% कोड के लिए कोड करते हैं जो आपके डेटाबेस को एक तकनीक से दूसरी तकनीक में बदलने जा रहा है? यदि आप अपने व्यवसाय की भविष्य की स्थिति के बारे में सोच रहे हैं और हां कहते हैं कि यह संभावना है तो a) उनके पास बहुत अधिक पैसा होना चाहिए ताकि वे किसी अन्य DB प्रौद्योगिकी या b के लिए माइग्रेशन कर सकें) ) आपके द्वारा उपयोग की जाने वाली पहली तकनीक के साथ कुछ बुरी तरह से गलत हो गया है।

अमीर LINQ सिंटैक्स को क्यों फेंक दें?

LINQ और EF को विकसित किया गया था ताकि आप इसे पढ़ने के लिए साफ-सुथरा सामान बना सकें और ऑब्जेक्ट ग्राफ को पार कर सकें। एक रिपॉजिटरी बनाना और बनाए रखना जो आपको वही लचीलापन दे सकता है जो एक राक्षसी कार्य है। मेरे अनुभव में किसी भी समय मैंने एक रिपॉजिटरी का निर्माण किया है जिसमें मैंने हमेशा व्यावसायिक लॉजिक को रिपोजिटरी लेयर में लीक किया है ताकि या तो प्रश्नों को अधिक प्रदर्शन योग्य बनाया जा सके और / या डेटाबेस को हिट की संख्या कम हो सके।

मैं किसी क्वेरी के हर एक क्रमपरिवर्तन के लिए एक विधि नहीं बनाना चाहता जिसे मुझे लिखना है। मैं संग्रहीत प्रक्रियाओं को भी लिख सकता हूं। मैं नहीं चाहता GetOrder, GetOrderWithOrderItem, GetOrderWithOrderItemWithOrderActivity, GetOrderByUserId, और इतने पर ... मैं सिर्फ मुख्य इकाई और पार प्राप्त करना चाहते हैं और के रूप में वस्तु ग्राफ में शामिल हैं मैं तो कृपया।

रिपॉजिटरी के अधिकांश उदाहरण बकवास हैं

जब तक आप ब्लॉग जैसी कुछ नंगे-नंबरों को विकसित नहीं कर रहे हैं या आपके प्रश्न कुछ भी सरल नहीं हैं, तो 90% उदाहरण आपको रिपॉजिटरी पैटर्न के आसपास के इंटरनेट पर मिलते हैं। मैं इस पर अधिक जोर नहीं दे सकता हूं! यह एक ऐसी चीज है जिसे किसी व्यक्ति को समझने के लिए कीचड़ के माध्यम से क्रॉल करना पड़ता है। हमेशा ऐसा होगा कि आपके द्वारा बनाए गए रिपॉजिटरी / सॉल्यूशन को तोड़ने वाली एक क्वेरी आपके द्वारा बनाई गई और वह उस बिंदु तक नहीं है, जब आप दूसरी बार खुद अनुमान लगाते हैं और तकनीकी ऋण / क्षरण शुरू होता है।

यूनिट मुझे परीक्षण नहीं भाई

लेकिन अगर मेरे पास भंडार नहीं है तो यूनिट परीक्षण के बारे में क्या होगा? मैं कैसे मजाक करूंगा? सरल, तुम नहीं। आइए इसे दोनों कोणों से देखें:

कोई रिपॉजिटरी नहीं - आप DbContextएक IDbContextया कुछ अन्य ट्रिक का उपयोग करके मॉक कर सकते हैं, लेकिन फिर आप वास्तव में यूनिट LINQ को ऑब्जेक्ट्स के लिए परीक्षण कर रहे हैं, न कि LINQ को एंटिटीज में । इसलिए अब इसे कवर करने के लिए एकीकरण परीक्षण तक है।

रिपॉजिटरी के साथ - अब आप अपनी रिपॉजिटरी को मॉक कर सकते हैं और यूनिट के बीच की परत (एस) का परीक्षण कर सकते हैं। महान सही है? वास्तव में ठीक नहीं है ... ऊपर के मामलों में जहां आपको डेटाबेस को हिट करने के लिए रिपॉजिटरी लेयर में लॉजिक लीक करना पड़ता है और डेटाबेस में कम हिट्स मिलते हैं, आपकी यूनिट टेस्ट को कैसे कवर कर सकती है? यह अब रेपो लेयर में है और आप IQueryable<T>सही परीक्षण नहीं करना चाहते हैं ? इसके अलावा आइए ईमानदार रहें, आपकी इकाई परीक्षण उन प्रश्नों को कवर करने के लिए नहीं हैं जिनमें 20 लाइन का .Where()खंड और है.Include()रिश्तों का एक गुच्छा और डेटाबेस को फिर से हिट करता है यह सब अन्य सामान, ब्ला, ब्ला, ब्लाह वैसे भी क्योंकि क्वेरी रनटाइम पर उत्पन्न होती है। जब से आपने ऊपरी परतों की दृढ़ता को अज्ञानी रखने के लिए एक रिपॉजिटरी का निर्माण किया, यदि आप अब अपनी डेटाबेस तकनीक को बदलना चाहते हैं, तो क्षमा करें, आपकी इकाई परीक्षण निश्चित रूप से रनटाइम पर समान परिणामों की गारंटी नहीं दे रहे हैं, एकीकरण परीक्षणों पर वापस। तो भंडार का पूरा बिंदु अजीब लगता है ।।

2 सेंट

जब हम सादा संग्रहित प्रक्रियाओं (थोक आवेषण, बल्क डिलीट, CTE, इत्यादि) पर EF का उपयोग करते हैं तो हम पहले ही बहुत अधिक कार्यक्षमता और वाक्यविन्यास खो देते हैं, लेकिन मैं C # में भी कोड करता हूं इसलिए मुझे बाइनरी टाइप करने की आवश्यकता नहीं है। हम ईएफ का उपयोग करते हैं, इसलिए हम विभिन्न प्रदाताओं का उपयोग करने और कई चीजों के बीच अच्छे संबंधित तरीके से ऑब्जेक्ट ग्राफ के साथ काम करने की संभावना रख सकते हैं। कुछ सार उपयोगी हैं और कुछ नहीं हैं।


17
आप उन्हें परीक्षण करने में सक्षम होने के लिए रिपॉजिटरी नहीं बनाते हैं। आप व्यावसायिक तर्क को इकाई परीक्षण में सक्षम होने के लिए रिपॉजिटरी बनाते हैं । यह सुनिश्चित करने के लिए कि प्रश्न काम करते हैं: रिपॉजिटरी के लिए एकीकरण परीक्षण लिखना बहुत आसान है क्योंकि उनमें केवल तर्क होते हैं और कोई व्यवसाय नहीं।
04

16
Coding for the exception: रिपॉजिटरी का उपयोग डेटाबेस इंजन को स्विच करने में सक्षम नहीं होना है। यह व्यवसाय को दृढ़ता से अलग करने के बारे में है।
jgauffin

2
ये सभी बहुत ही मान्य बिंदु हैं जिनके पीछे बहुत हद तक सच्चाई है। लेकिन जो कमी है वह यह है कि LINQ एक सुसंगत स्थान के लिए विवश करने के बजाय एक अनुप्रयोग के बारे में बताया गया है जो कोडेहैंड पृष्ठों में SQL कॉल के बराबर EF बनाता है। प्रत्येक LINQ क्वेरी एक अनुप्रयोग में एक संभावित रखरखाव बिंदु है, और जितने अधिक हैं (और वे जितने अधिक व्यापक हैं), रखरखाव की लागत और जोखिम जितना अधिक होगा। एक इकाई में एक 'हटाए गए' ध्वज को जोड़ने की कल्पना करें और उस बड़े अनुप्रयोग में हर एक जगह का पता लगाएं, जो उस इकाई से जुड़ा हुआ है, प्रत्येक को संशोधित करने के लिए ...
DVK

2
मुझे लगता है कि यह अदूरदर्शी और जेडेड है। आप रेपो में तर्क क्यों लीक करेंगे? और अगर तुमने किया, तो बात क्यों होगी? यह एक डेटा कार्यान्वयन है। हम जो कुछ कर रहे हैं, वह रेपो के पीछे छिपाकर LINQ के बाकी कोड से दीवार बना रहा है। आप कहते हैं कि इसका परीक्षण न करें, लेकिन तब आप इसे करने के खिलाफ तर्क के रूप में परीक्षण करने में सक्षम नहीं होते हैं। इसलिए रेपो बनाएं, IQueryable को उजागर न करें, और इसका परीक्षण न करें। कम से कम आप डेटा कार्यान्वयन से अलगाव में बाकी सब का परीक्षण कर सकते हैं। और यह कि एक db परिवर्तन का 1% मौका अभी भी एक विशाल $ $-भारी है।
सिनास्टेटिक जूल

5
इस उत्तर के लिए +1। मुझे लगता है कि हमें वास्तव में Entity Framework Core के साथ रिपॉजिटरी की आवश्यकता नहीं है। DbSetहै भंडार है, और DbContextहै कार्य की इकाई । जब ओआरएम हमारे लिए पहले से ही रिपॉजिटरी पैटर्न लागू कर रहा है! परीक्षण के लिए, बस प्रदाता को बदल दें InMemory। और अपने परीक्षण करते हैं! यह MSDN में अच्छी तरह से प्रलेखित है।
मोहम्मद नौरेलिन

49

रिपॉजिटरी पैटर्न एक अमूर्त है । इसका उद्देश्य जटिलता को कम करना और बाकी कोड को अज्ञानतापूर्ण बनाना है। एक बोनस के रूप में यह आपको एकीकरण परीक्षणों के बजाय इकाई परीक्षण लिखने की अनुमति देता है ।

समस्या यह है कि कई डेवलपर्स पैटर्न उद्देश्य को समझने में विफल रहते हैं और रिपॉजिटरी बनाते हैं जो फोन करने वाले (आमतौर पर उजागर करके IQueryable<T>) तक विशिष्ट जानकारी को लीक करते हैं । ऐसा करने से उन्हें सीधे OR / M का उपयोग करने पर कोई लाभ नहीं मिलता है।

किसी अन्य उत्तर को संबोधित करने के लिए अद्यतन करें

अपवाद के लिए कोडिंग

रिपॉजिटरी का उपयोग करना दृढ़ता प्रौद्योगिकी को बदलने में सक्षम नहीं है (अर्थात डेटाबेस को बदलना या इसके बजाय एक वेबसेवा आदि का उपयोग करना)। यह जटिलता और युग्मन को कम करने के लिए व्यवसाय तर्क को दृढ़ता से अलग करने के बारे में है।

इकाई परीक्षण बनाम एकीकरण परीक्षण

आप रिपॉजिटरी के लिए यूनिट टेस्ट नहीं लिखते हैं। अवधि।

लेकिन रिपॉजिटरी (या दृढ़ता और व्यवसाय के बीच कोई अन्य अमूर्त परत) की शुरुआत करके आप व्यावसायिक तर्क के लिए इकाई परीक्षण लिखने में सक्षम हैं। यानी गलत तरीके से कॉन्फ़िगर किए गए डेटाबेस के कारण आपको अपने परीक्षणों के असफल होने की चिंता नहीं है।

प्रश्नों के लिए के रूप में। यदि आप LINQ का उपयोग करते हैं तो आपको यह भी सुनिश्चित करना होगा कि आपके क्वेरीज़ काम करें, जैसे कि आपको रिपॉजिटरी के साथ करना है। और यह एकीकरण परीक्षणों का उपयोग करके किया जाता है।

अंतर यह है कि यदि आपने अपने व्यवसाय को LINQ कथनों के साथ नहीं मिलाया है तो आप 100% सुनिश्चित हो सकते हैं कि यह आपका दृढ़ता कोड है जो विफल हो रहा है और कुछ और नहीं।

यदि आप अपने परीक्षणों का विश्लेषण करते हैं, तो आप यह भी देखेंगे कि यदि आपको मिश्रित चिंताएं नहीं हैं, तो वे अधिक साफ-सुथरे होंगे (जैसे कि LINQ + व्यावसायिक तर्क)

रिपोजिटरी के उदाहरण

ज्यादातर उदाहरण बकवास हैं। यह बिल्कुल सच है। हालाँकि, यदि आप किसी भी डिज़ाइन पैटर्न को गूगल करते हैं तो आपको बहुत सारे भद्दे उदाहरण मिलेंगे। पैटर्न का उपयोग करने से बचने का कोई कारण नहीं है।

एक सही रिपॉजिटरी कार्यान्वयन का निर्माण बहुत आसान है। वास्तव में, आपको केवल एक नियम का पालन करना होगा:

जब तक आपको इसकी आवश्यकता न हो, तब तक रिपॉजिटरी क्लास में कुछ भी न जोड़ें

बहुत सारे कोडर आलसी होते हैं और एक सामान्य रिपॉजिटरी बनाने की कोशिश करते हैं और बहुत सारे तरीकों के साथ एक बेस क्लास का उपयोग करते हैं जिनकी उन्हें आवश्यकता हो सकती है। YAGNI। आप एक बार रिपॉजिटरी क्लास लिखते हैं और इसे तब तक रखते हैं जब तक एप्लिकेशन रहता है (वर्ष हो सकता है)। क्यों आलसी होकर इसे चोदना। बिना किसी बेस क्लास इनहेरिटेंस के इसे साफ रखें। यह पढ़ने और बनाए रखने में बहुत आसान बना देगा।

(उपरोक्त कथन एक दिशानिर्देश है और एक कानून नहीं है। एक आधार वर्ग बहुत अच्छी तरह से प्रेरित हो सकता है। बस इसे जोड़ने से पहले सोचें, ताकि आप इसे सही कारणों से जोड़ दें)

पुरानी सामग्री

निष्कर्ष:

यदि आपको अपने व्यावसायिक कोड में LINQ स्टेटमेंट्स से कोई आपत्ति नहीं है और न ही यूनिट परीक्षणों की परवाह है तो मुझे सीधे एंटिटी फ्रेमवर्क का उपयोग न करने का कोई कारण नहीं दिखता है।

अपडेट करें

मैंने रिपॉजिटरी पैटर्न के बारे में ब्लॉग किया है और "अमूर्त" का वास्तव में क्या मतलब है: http://blog.gauffin.org/2013/01/repository-pattern-done-right/

अपडेट २

20+ फ़ील्ड के साथ एकल इकाई प्रकार के लिए, आप किसी भी क्रमपरिवर्तन संयोजन का समर्थन करने के लिए क्वेरी विधि कैसे डिज़ाइन करेंगे? आप केवल नाम से खोज को सीमित नहीं करना चाहते, नेविगेशन गुणों के साथ क्या खोज रहे हैं, विशिष्ट मूल्य कोड के साथ आइटम के साथ सभी आदेशों को सूचीबद्ध करें, नेविगेशन खोज खोज का 3 स्तर। पूरे कारण IQueryableका आविष्कार किया गया था जो डेटाबेस के खिलाफ खोज के किसी भी संयोजन को बनाने में सक्षम था। सिद्धांत में सब कुछ बहुत अच्छा लगता है, लेकिन उपयोगकर्ता की जरूरत सिद्धांत से ऊपर जीतती है।

दोबारा: 20+ फ़ील्ड वाली इकाई को गलत तरीके से मॉडल किया गया है। यह एक भगवान इकाई है। तोड़ दो।

मैं तर्क नहीं कर रहा हूँ कि IQueryableक्वेरिंग के लिए नहीं बनाया गया था। मैं कह रहा हूँ कि यह रिसाव के बाद से रिपॉजिटरी पैटर्न जैसी अमूर्त परत के लिए सही नहीं है । कोई 100% पूर्ण LINQ To Sql प्रदाता (EF की तरह) नहीं है।

उन सभी के पास विशिष्ट चीजें हैं जैसे कि उत्सुक / आलसी लोडिंग का उपयोग कैसे करें या एसक्यूएल "इन" स्टेटमेंट कैसे करें। IQueryableरिपॉजिटरी में एक्सपोजर उपयोगकर्ता को उन सभी चीजों को जानने के लिए मजबूर करता है। इस प्रकार डेटा स्रोत को दूर करने का पूरा प्रयास एक पूर्ण विफलता है। आप सीधे OR / M का उपयोग करने पर कोई लाभ प्राप्त किए बिना केवल जटिलता जोड़ते हैं।

या तो रिपॉजिटरी पैटर्न को सही तरीके से लागू करें या बस इसका इस्तेमाल बिल्कुल न करें।

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


6
IQueryable को उजागर नहीं करने से सीमित खोज होती है, और लोग विभिन्न प्रकार के प्रश्नों के लिए अधिक तरीके प्राप्त करते हैं, और अंततः यह रिपॉजिटरी को और अधिक जटिल बना देता है।
आकाश काव

3
आपने मुख्य मुद्दे को बिल्कुल भी संबोधित नहीं किया है: रिपोजिटरी के माध्यम से IQueryable को एक्सपोज करना पूर्ण अमूर्त नहीं है।
jagauffin

1
एक क्वेरी ऑब्जेक्ट का होना जिसमें सभी आवश्यक बुनियादी ढांचे को निष्पादित किया जाना है और खुद को imo जाने का तरीका है। आप इसे वे फ़ील्ड देते हैं जो खोज शब्द हैं और यह परिणामों की सूची लौटाता है। QO के लिए आंतरिक आप जो चाहें कर सकते हैं। और यह एक इंटरफ़ेस है, इसलिए आसानी से परीक्षण किया जाता है। ऊपर मेरी पोस्ट देखें। यह सर्वोत्तम हैं।
h.xx

2
व्यक्तिगत रूप से, मुझे लगता है कि इसका एक सदस्य पर अंतर्निहित सेट को उजागर करने के बजाय एक रिपॉजिटरी वर्ग पर IQueryable <T> इंटरफ़ेस को लागू करना भी समझ में आता है।
dark_perfect

3
@yat: प्रति समूह एक रिपॉजिट। लेकिन imho यह रूट और टेबल का एग्रीगेट नहीं बल्कि सिर्फ एग्रीगेट रूट और एग्रीगेट है । वास्तविक संग्रहण केवल एक तालिका या उनमें से बहुत से उपयोग कर सकते हैं, अर्थात यह प्रत्येक समुच्चय और तालिका के बीच एक-एक मानचित्रण नहीं हो सकता है। मैं जटिलता को कम करने और अंतर्निहित भंडारण की किसी भी निर्भरता को दूर करने के लिए रिपॉजिटरी का उपयोग करता हूं।
jgauffin

27

IMO Repositoryअमूर्त और अमूर्त दोनों का UnitOfWorkकिसी भी सार्थक विकास में बहुत मूल्यवान स्थान है। लोग कार्यान्वयन विवरणों के बारे में बहस करेंगे, लेकिन जिस तरह एक बिल्ली को त्वचा देने के कई तरीके हैं, उसी तरह एक अमूर्त को लागू करने के कई तरीके हैं।

आपका प्रश्न विशेष रूप से उपयोग करने या नहीं करने के लिए है और क्यों।

जैसा कि आपको कोई संदेह नहीं है कि आपको पहले से ही इन दोनों पैटर्नों को एंटिटी फ्रेमवर्क में बनाया गया है, DbContextहै UnitOfWorkऔर DbSetहै Repository। आपको आमतौर पर इकाई परीक्षण UnitOfWorkया Repositoryखुद की आवश्यकता नहीं है क्योंकि वे बस आपकी कक्षाओं और अंतर्निहित डेटा एक्सेस कार्यान्वयन के बीच सुविधा प्रदान कर रहे हैं। यूनिट को आपकी सेवाओं के तर्क का परीक्षण करते समय, आपको बार-बार खुद को ऐसा करने की आवश्यकता होगी, जो इन दो अमूर्तों का मजाक उड़ाता है।

आप परीक्षण कर रहे तर्क और परीक्षण किए जा रहे तर्क के बीच कोड निर्भरता की परतों (जो आप को नियंत्रित नहीं करते हैं) जोड़कर बाहरी पुस्तकालयों के साथ नकली या जो भी कर सकते हैं, नकली कर सकते हैं ।

तो एक मामूली बात यह है कि अपने यूनिट परीक्षण का मजाक उड़ाते समय आपके पास खुद के लिए अमूर्तता है UnitOfWorkऔर Repositoryआपको अधिकतम नियंत्रण और लचीलापन देता है।

सभी बहुत अच्छी तरह से, लेकिन मेरे लिए, इन अमूर्तों की वास्तविक शक्ति यह है कि वे एस्पेक्ट ओरिएंटेड प्रोग्रामिंग तकनीकों को लागू करने और एसओएलआईडी सिद्धांतों का पालन करने का एक सरल तरीका प्रदान करते हैं ।

तो आप अपने IRepository:

public interface IRepository<T>
    where T : class
{
    T Add(T entity);
    void Delete(T entity);
    IQueryable<T> AsQueryable();
}

और इसका कार्यान्वयन:

public class Repository<T> : IRepository<T>
    where T : class
{
    private readonly IDbSet<T> _dbSet;
    public Repository(PPContext context) 
    {
        _dbSet = context.Set<T>();
    }

    public T Add(T entity)
    { 
        return _dbSet.Add(entity); 
    }

    public void Delete(T entity)
    {
        _dbSet.Remove(entity); 
    }

    public IQueryable<T> AsQueryable() 
    {
        return _dbSet.AsQueryable();
    }
}

साधारण से बाहर कुछ भी नहीं है, लेकिन अब हम एक लॉगिंग डेकोरेटर के साथ कुछ लॉगिंग - आसान जोड़ना चाहते हैं ।

public class RepositoryLoggerDecorator<T> : IRepository<T>
    where T : class
{
    Logger logger = LogManager.GetCurrentClassLogger();
    private readonly IRepository<T> _decorated;
    public RepositoryLoggerDecorator(IRepository<T> decorated)
    {
        _decorated = decorated;
    }

    public T Add(T entity)
    {
        logger.Log(LogLevel.Debug, () => DateTime.Now.ToLongTimeString() );
        T added = _decorated.Add(entity);
        logger.Log(LogLevel.Debug, () => DateTime.Now.ToLongTimeString());
        return added;
    }

    public void Delete(T entity)
    {
        logger.Log(LogLevel.Debug, () => DateTime.Now.ToLongTimeString());
        _decorated.Delete(entity);
        logger.Log(LogLevel.Debug, () => DateTime.Now.ToLongTimeString());
    }

    public IQueryable<T> AsQueryable()
    {
        return _decorated.AsQueryable();
    }
}

सब किया और हमारे मौजूदा कोड में कोई बदलाव नहीं किया । कई अन्य क्रॉस कटिंग चिंताएं हैं जिन्हें हम जोड़ सकते हैं, जैसे कि अपवाद हैंडलिंग, डेटा कैशिंग, डेटा सत्यापन या जो कुछ भी और हमारे पूरे डिजाइन और निर्माण की प्रक्रिया में हमारे पास सबसे मूल्यवान चीज है जो हमें किसी भी मौजूदा कोड को बदलने के बिना सरल सुविधाओं को जोड़ने में सक्षम बनाती है। हमारा IRepositoryअमूर्त है

अब, कई बार मैंने स्टैकऑवरफ्लो पर यह प्रश्न देखा है - "आप बहु किरायेदार वातावरण में एंटिटी फ्रेमवर्क कैसे बनाते हैं?"

https://stackoverflow.com/search?q=%5Bentity-framework%5D+multi+tenant

यदि आपके पास Repositoryअमूर्तता है, तो उत्तर है "यह एक डेकोरेटर जोड़ना आसान है"

public class RepositoryTennantFilterDecorator<T> : IRepository<T>
    where T : class
{
    //public for Unit Test example
    public readonly IRepository<T> _decorated;
    public RepositoryTennantFilterDecorator(IRepository<T> decorated)
    {
        _decorated = decorated;
    }

    public T Add(T entity)
    {
        return _decorated.Add(entity);
    }

    public void Delete(T entity)
    {
        _decorated.Delete(entity);
    }

    public IQueryable<T> AsQueryable()
    {
        return _decorated.AsQueryable().Where(o => true);
    }
}

IMO आपको हमेशा किसी भी 3 पार्टी घटक पर एक साधारण अमूर्त जगह देनी चाहिए जो एक से अधिक स्थानों पर संदर्भित होगी। इस दृष्टिकोण से एक ORM सही उम्मीदवार है क्योंकि यह हमारे कोड के बहुत में संदर्भित है।

इसका जवाब जो आम तौर पर दिमाग में आता है जब कोई कहता है कि "मुझे Repositoryइस या उस 3 पार्टी लाइब्रेरी पर अमूर्तता (जैसे ) क्यों होनी चाहिए " क्या आप क्यों नहीं? "

पीएस डेकोरेटर्स आईओसी कंटेनर का उपयोग करके लागू करने के लिए बेहद सरल हैं, जैसे कि सिम्पलइन्जेक्टर

[TestFixture]
public class IRepositoryTesting
{
    [Test]
    public void IRepository_ContainerRegisteredWithTwoDecorators_ReturnsDecoratedRepository()
    {
        Container container = new Container();
        container.RegisterLifetimeScope<PPContext>();
        container.RegisterOpenGeneric(
            typeof(IRepository<>), 
            typeof(Repository<>));
        container.RegisterDecorator(
            typeof(IRepository<>), 
            typeof(RepositoryLoggerDecorator<>));
        container.RegisterDecorator(
            typeof(IRepository<>), 
            typeof(RepositoryTennantFilterDecorator<>));
        container.Verify();

        using (container.BeginLifetimeScope())
        {
            var result = container.GetInstance<IRepository<Image>>();

            Assert.That(
                result, 
                Is.InstanceOf(typeof(RepositoryTennantFilterDecorator<Image>)));
            Assert.That(
                (result as RepositoryTennantFilterDecorator<Image>)._decorated,
                Is.InstanceOf(typeof(RepositoryLoggerDecorator<Image>)));
        }
    }
}

11

सबसे पहले, जैसा कि कुछ उत्तर द्वारा सुझाया गया है, ईएफ स्वयं एक रिपॉजिटरी पैटर्न है, इसे रिपॉजिटरी के रूप में नाम देने के लिए आगे अमूर्त बनाने की कोई आवश्यकता नहीं है।

यूनिट टेस्ट के लिए नकली रिपोजिटरी, क्या हमें वास्तव में इसकी आवश्यकता है?

हम EF को SQL टेस्ट DB के विरुद्ध सीधे हमारे व्यावसायिक तर्क का परीक्षण करने के लिए इकाई परीक्षणों में DB का परीक्षण करने के लिए संवाद करने देते हैं। मुझे किसी भी रिपॉजिटरी पैटर्न का मजाक बनाने का कोई फायदा नहीं दिखता है। परीक्षण डेटाबेस के विरुद्ध इकाई परीक्षण करना वास्तव में गलत क्या है? जैसा कि यह थोक संचालन संभव नहीं है और हम कच्चे एसक्यूएल लिखना समाप्त करते हैं। मेमोरी में SQLite वास्तविक डेटाबेस के खिलाफ इकाई परीक्षण करने के लिए एकदम सही उम्मीदवार है।

अनावश्यक अमूर्तता

क्या आप रिपॉजिटरी बनाना चाहते हैं ताकि भविष्य में आप आसानी से ईएफ को एनएचबाइबरनेट आदि या किसी अन्य चीज से बदल सकें? शानदार योजना लगती है, लेकिन क्या यह वास्तव में प्रभावी है?

Linq यूनिट परीक्षणों को मारता है?

मैं किसी भी उदाहरण को देखना चाहूंगा कि यह कैसे मार सकता है।

निर्भरता इंजेक्शन, IoC

वाह ये महान शब्द हैं, यकीन है कि वे सिद्धांत में बहुत अच्छे लगते हैं, लेकिन कभी-कभी आपको महान डिजाइन और महान समाधान के बीच व्यापार बंद करना होगा। हमने उस सभी का उपयोग किया, और हमने सभी कचरा फेंकने और अलग-अलग दृष्टिकोण का चयन किया। आकार बनाम गति (कोड का आकार और विकास की गति) वास्तविक जीवन में बहुत बड़ा है। उपयोगकर्ताओं को लचीलेपन की आवश्यकता होती है, उन्हें परवाह नहीं है कि आपका कोड डि या आईओसी के संदर्भ में डिजाइन में महान है या नहीं।

जब तक आप Visual Studio का निर्माण नहीं कर रहे हैं

इन सभी महान डिजाइनों की आवश्यकता है यदि आप विजुअल स्टूडियो या एक्लिप्स जैसे जटिल कार्यक्रम का निर्माण कर रहे हैं जो कई लोगों द्वारा विकसित किया जाएगा और इसे अत्यधिक अनुकूलन योग्य बनाने की आवश्यकता है। इन IDEs के विकास के वर्षों के बाद सभी महान विकास पैटर्न चित्र में आए, और वे उस स्थान पर विकसित हुए हैं जहाँ ये सभी महान डिजाइन पैटर्न बहुत मायने रखते हैं। लेकिन अगर आप साधारण वेब आधारित पेरोल, या सरल व्यवसाय ऐप कर रहे हैं, तो बेहतर है कि आप समय के साथ अपने विकास में विकसित हों, बजाय इसके कि इसे बनाने के लिए समय खर्च करने के लिए मिलियन उपयोगकर्ताओं के लिए जहां यह केवल 100 उपयोगकर्ताओं के लिए तैनात किया जाएगा।

फ़िल्टर किए गए दृश्य के रूप में भंडार - ISecureRepository

दूसरी तरफ, रिपॉजिटरी ईएफ का एक फ़िल्टर किया गया दृश्य होना चाहिए जो वर्तमान उपयोगकर्ता या भूमिका के आधार पर आवश्यक भराव को लागू करके डेटा तक पहुंच प्रदान करता है।

लेकिन ऐसा करने से रिपॉजिटरी और भी जटिल हो जाती है क्योंकि इसे बनाए रखने के लिए विशाल कोड बेस में समाप्त हो जाता है। लोग अलग-अलग उपयोगकर्ता प्रकारों या इकाई प्रकारों के संयोजन के लिए विभिन्न रिपॉजिटरी का निर्माण करते हैं। यही नहीं, हम बहुत सारे डीटीओ के साथ भी काम करते हैं।

निम्नलिखित उत्तर कक्षाओं और तरीकों के पूरे सेट को बनाए बिना फ़िल्टर रिपॉजिटरी का एक उदाहरण कार्यान्वयन है। यह सीधे सवाल का जवाब नहीं दे सकता है, लेकिन यह एक को प्राप्त करने में उपयोगी हो सकता है।

अस्वीकरण: मैं एंटिटी रेस्ट एसडीके का लेखक हूं।

http://entityrestsdk.codeplex.com

ऊपर ध्यान में रखते हुए, हमने एक SDK विकसित किया, जो SecurityContext के आधार पर फ़िल्टर किए गए दृश्य का भंडार बनाता है जो JUD संचालन के लिए फ़िल्टर रखता है। और केवल दो प्रकार के नियम किसी भी जटिल ऑपरेशन को सरल बनाते हैं। पहले इकाई तक पहुंच है, और अन्य संपत्ति के लिए नियम पढ़ें / लिखें।

लाभ यह है, कि आप विभिन्न उपयोगकर्ता प्रकारों के लिए व्यावसायिक तर्क या रिपॉजिटरी को फिर से नहीं लिखते हैं, आप बस उन्हें ब्लॉक या अनुदान प्रदान करते हैं।

public class DefaultSecurityContext : BaseSecurityContext {

  public static DefaultSecurityContext Instance = new DefaultSecurityContext();

  // UserID for currently logged in User
  public static long UserID{
       get{
             return long.Parse( HttpContext.Current.User.Identity.Name );
       }
  }

  public DefaultSecurityContext(){
  }

  protected override void OnCreate(){

        // User can access his own Account only
        var acc = CreateRules<Account>();

        acc.SetRead( y => x=> x.AccountID == UserID ) ;
        acc.SetWrite( y => x=> x.AccountID == UserID );

        // User can only modify AccountName and EmailAddress fields
        acc.SetProperties( SecurityRules.ReadWrite, 
              x => x.AccountName,
              x => x.EmailAddress);

        // User can read AccountType field
        acc.SetProperties<Account>( SecurityRules.Read, 
              x => x.AccountType);

        // User can access his own Orders only
        var order = CreateRules<Order>();
        order.SetRead( y => x => x.CustomerID == UserID );

        // User can modify Order only if OrderStatus is not complete
        order.SetWrite( y => x => x.CustomerID == UserID 
            && x.OrderStatus != "Complete" );

        // User can only modify OrderNotes and OrderStatus
        order.SetProperties( SecurityRules.ReadWrite, 
              x => x.OrderNotes,
              x => x.OrderStatus );

        // User can not delete orders
        order.SetDelete(order.NotSupportedRule);
  }
}

ये LINQ नियम हर ऑपरेशन के लिए SaveChanges विधि में डेटाबेस के खिलाफ मूल्यांकन किए जाते हैं, और ये नियम डेटाबेस के सामने फ़ायरवॉल के रूप में कार्य करते हैं।


3
एक DB के खिलाफ यूनिट परीक्षण का मतलब है कि आपके परीक्षणों के लिए आपके पास अतिरिक्त आवश्यकता है। यदि वह DB डाउन है, या डेटा क्लियर हो जाता है, या उस DB के साथ कुछ भी होता है, तो आपके परीक्षण विफल हो जाएंगे। यह वांछित नहीं है। IQueryable को उजागर करने वाले भंडार सेटअप के बारे में 2 मिनट लगते हैं। यहां समय बर्बाद नहीं हुआ। DI ने आपको लंबा समय क्यों लिया? यह सब टकसाल लेता है। मैं कहता हूँ कि यह सब मेरी सेवा परत में मेरे जटिल प्रश्नों के परीक्षण के लिए महान काम कर रहा है। इससे जुड़ने के लिए डेटाबेस की जरूरत नहीं थी इसलिए बहुत अच्छा लगा। नगेट से एक नकली रूपरेखा प्राप्त करना लगभग एक मिनट लगा। इस सामान में कोई समय नहीं लगता है।
user441521

@ user441521 सेटअप के लिए IQueryable 2 मिनट के साथ रिपोजिटरी? आप किस दुनिया में रह रहे हैं, हमारी लाइव साइट पर प्रत्येक asp.net अनुरोध मिलीसेकंड के भीतर परोसा जाता है। मॉकिंग और फेकिंग आदि कोड में अधिक जटिलता जोड़ता है, इसका कुल समय बर्बाद होता है। जब यूनिट को व्यावसायिक तर्क इकाई के रूप में परिभाषित नहीं किया जाता है तो यूनिट परीक्षण बेकार होते हैं।
आकाश काव

7

इस पर बहुत बहस है कि कौन सी विधि सही है, इसलिए मैं इसे देखता हूं क्योंकि दोनों स्वीकार्य हैं इसलिए मैं कभी भी उपयोग करता हूं जो मुझे सबसे ज्यादा पसंद है (जो कोई रिपॉजिटरी नहीं है, यूओडब्ल्यू)।

EF में UoW को DbContext के माध्यम से कार्यान्वित किया जाता है और DbSets रिपॉजिटरी हैं।

डेटा लेयर के साथ काम करने के तरीके के रूप में मैं सीधे DbContext ऑब्जेक्ट पर काम करता हूं, जटिल प्रश्नों के लिए मैं उस क्वेरी के लिए एक्सटेंशन विधियां बनाऊंगा जिन्हें पुन: उपयोग किया जा सकता है।

मेरा मानना ​​है कि आयेंडे के पास कुछ पोस्ट भी हैं कि सीयूडी संचालन कैसे अमूर्त है।

मैं हमेशा एक इंटरफ़ेस बनाता हूं और मेरा संदर्भ इससे विरासत में मिलता है इसलिए मैं DI के लिए IoC कंटेनर का उपयोग कर सकता हूं।


तो विस्तार के तरीके, वे कितने व्यापक हैं? कहते हैं कि मुझे अपने विस्तार में एक और इकाई की स्थिति प्राप्त करने की आवश्यकता है? यही मेरी सबसे बड़ी चिंता है। आप विस्तार विधियों के कुछ उदाहरण दिखाते हैं?
देजन

ayende.com/blog/153473/… और ayende.com/blog/153569/… । (ये एक आर्किटेक्चर (फ्रेमवर्क?) की समीक्षा हैं, जिसे s # arp lite कहा जाता है। ज्यादातर अच्छा है लेकिन वह रिपॉजिटरी और CUD के सार से असहमत हैं)।
जोश

इसका NHibernate आधारित है। क्या आपको EF का उपयोग करके कोई उदाहरण नहीं मिला है? और फिर से जब मुझे एक और इकाई को कॉल करने की आवश्यकता होती है तो यह कैसे स्थिर विस्तार विधि में सबसे अच्छा बनाया जाता है?
देजान।

3
यह सब ठीक है और अच्छा है जब तक कि आपके डोमेन ऑब्जेक्ट की संपत्ति को आपके डेटाबेस में संग्रहीत डेटा द्वारा हाइड्रेटेड करने की आवश्यकता न हो; या आपको एक ऐसी तकनीक को छोड़ना होगा जो आपके फूला हुआ ओआरएम की तुलना में अधिक प्रदर्शन योग्य है। उफ़! एक ORM केवल एक रिपॉजिटरी के लिए एक प्रतिस्थापन नहीं है, यह एक का कार्यान्वयन विवरण है।
cdaq

2

EF पर जो सबसे अधिक लागू होता है वह रिपोजिटरी पैटर्न नहीं है। यह एक मुखौटा पैटर्न है (कॉल को सरल बनाने में आसान है, संस्करणों का उपयोग करने के लिए ईएफ विधियों को कॉल करना)।

EF रिपॉजिटरी पैटर्न (और कार्य पैटर्न की इकाई) को लागू करने वाला एक है। यही है, EF डेटा एक्सेस लेयर को एब्सट्रैक्ट करने वाला एक है ताकि उपयोगकर्ता को पता न हो कि वे SQLServer के साथ काम कर रहे हैं।

और उस पर, EF पर अधिकांश "रिपॉजिटरी" भी अच्छे पहलू नहीं हैं क्योंकि वे केवल नक्शे, काफी सीधे, ईएफ में एकल तरीकों तक, यहां तक ​​कि समान हस्ताक्षर होने के बिंदु तक भी हैं।

EF पर इस तथाकथित "रिपॉजिटरी" पैटर्न को लागू करने के लिए दो कारणों से, आसान परीक्षण की अनुमति देना और इसके लिए "कैन्ड" कॉलों का सबसेट स्थापित करना है। अपने आप में बुरा नहीं है, लेकिन स्पष्ट रूप से एक रिपोजिटरी नहीं है।


1

लिनक आजकल pos रिपोजिटरी ’है।

ISession + Linq पहले से ही भंडार है, और आपको न तो GetXByYतरीकों की आवश्यकता है और न ही QueryData(Query q)सामान्यीकरण की। DAL उपयोग के लिए थोड़ा पागल होने के नाते, मैं अभी भी रिपॉजिटरी इंटरफ़ेस पसंद करता हूं। (स्थिरता की दृष्टि से हमें अभी भी विशिष्ट डेटा एक्सेस इंटरफेस पर कुछ मोहरा होना चाहिए)।

यहां हम रिपॉजिटरी का उपयोग करते हैं - यह हमें निहर्नेट के प्रत्यक्ष उपयोग से हटाता है, लेकिन लाइनक इंटरफ़ेस प्रदान करता है (जैसा कि असाधारण मामलों में आईएसएएस एक्सेस है, जो अंततः रिफ्लेक्टर के अधीन हैं)।

class Repo
{
    ISession _session; //via ioc
    IQueryable<T> Query()
    {
        return _session.Query<T>();
    }
}

आप सर्विस लेयर के लिए क्या करते हैं?
देजन

नियंत्रक केवल पढ़ने के लिए डेटा के लिए रेपो क्वेरी करते हैं, कुछ अतिरिक्त परत क्यों जोड़ते हैं? दूसरी संभावना "ContentService" का उपयोग कर रही है, जो अधिक से अधिक एक सेवा-स्तर-रिपॉजिटरी होने के लिए जाता है: GetXByY, etcetc। संशोधन कार्यों के लिए - आवेदन सेवाएं उपयोग के मामलों में केवल सार हैं - वे बीएल और रेपो का उपयोग स्वतंत्र रूप से करते हैं ..
मिकालाई

मुझे बिजनेस लॉजिक के लिए सर्विस लेयर करने की आदत है। मुझे यकीन नहीं है कि मैं आपको ContentService के साथ अनुसरण करता हूं, कृपया विस्तृत करें। क्या सहायक सेवा के रूप में सहायक वर्गों को करना बुरा होगा?
दे.जान

'सर्विस लेयर' से मेरा मतलब 'एप्लीकेशन सर्विसेज' से था। वे रिपॉजिटरी और डोमेन लेयर के किसी भी अन्य सार्वजनिक हिस्से का उपयोग कर सकते हैं। "सेवा परत" बुरा अभ्यास नहीं है, लेकिन मैं केवल सूची <x> परिणाम प्रदान करने के लिए XService वर्ग बनाने से बचता हूँ। विवरण में सेवाओं का वर्णन करने के लिए टिप्पणी क्षेत्र बहुत छोटा प्रतीत होता है, क्षमा करें।
मिकलाई

क्या होगा अगर, एक कार्ट गणना की अनुमति देता है और आपको गणना करने के लिए एप्लिकेशन सेटिंग्स पैरामीटर और विशिष्ट ग्राहक पैरामीटर प्राप्त करने की आवश्यकता होती है, और आवेदन में कई स्थानों पर इसका पुन: उपयोग किया जाता है। आप उस स्थिति को कैसे संभालते हैं? सहायक वर्ग या आवेदन सेवा?
देजन।

1

भंडार इस समय (या तथापि एक चुन लेगा इसे कहते हैं) के लिए मुझे हठ परत दूर सार संक्षेप के बारे में ज्यादातर है।

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

इसलिए, मेरे पास है

public interface IRepository : IDisposable
{
    void Save<TEntity>(TEntity entity);
    void SaveList<TEntity>(IEnumerable<TEntity> entities);

    void Delete<TEntity>(TEntity entity);
    void DeleteList<TEntity>(IEnumerable<TEntity> entities);

    IList<TEntity> GetAll<TEntity>() where TEntity : class;
    int GetCount<TEntity>() where TEntity : class;

    void StartConversation();
    void EndConversation();

    //if query objects can be self sustaining (i.e. not need additional configuration - think session), there is no need to include this method in the repository.
    TResult ExecuteQuery<TResult>(IQueryObject<TResult> query);
}

संभवतः कॉलबैक के साथ async विधियों को डेलिगेट्स के रूप में जोड़ें। रेपो उदारतापूर्वक लागू करना आसान है , इसलिए मैं ऐप से ऐप तक कार्यान्वयन की एक पंक्ति को छूने में सक्षम नहीं हूं। खैर, यह सच है कि कम से कम एनएच का उपयोग करते समय, मैंने इसे ईएफ के साथ भी किया, लेकिन मुझे ईएफ से नफरत है। 4. बातचीत एक लेनदेन की शुरुआत है। कुछ वर्ग रिपॉजिटरी उदाहरण साझा करते हैं तो बहुत अच्छा है। इसके अलावा, एनएच के लिए, मेरे कार्यान्वयन में एक रेपो एक सत्र के बराबर है जो पहले अनुरोध पर खोला गया है।

फिर क्वेरी ऑब्जेक्ट्स

public interface IQueryObject<TResult>
{
    /// <summary>Provides configuration options.</summary>
    /// <remarks>
    /// If the query object is used through a repository this method might or might not be called depending on the particular implementation of a repository.
    /// If not used through a repository, it can be useful as a configuration option.
    /// </remarks>
    void Configure(object parameter);

    /// <summary>Implementation of the query.</summary>
    TResult GetResult();
}

कॉन्फ़िगर करने के लिए मैं NH में केवल ISession में पास करने के लिए उपयोग करता हूं। ईएफ में कम या ज्यादा का कोई मतलब नहीं है।

एक उदाहरण क्वेरी होगी .. (NH)

public class GetAll<TEntity> : AbstractQueryObject<IList<TEntity>>
    where TEntity : class
{
    public override IList<TEntity> GetResult()
    {
        return this.Session.CreateCriteria<TEntity>().List<TEntity>();
    }
}

EF क्वेरी करने के लिए आपको सार बेस में संदर्भ रखना होगा, न कि सत्र। लेकिन बेशक इफ वही होगा।

इस तरह से प्रश्नों को स्वयं समझाया जाता है, और आसानी से परीक्षण किया जा सकता है। सबसे अच्छा, मेरा कोड केवल इंटरफेस पर निर्भर करता है। सब कुछ बहुत साफ है। डोमेन (व्यवसाय) वस्तुएं बस इतनी ही हैं, जैसे कि सक्रिय रिकॉर्ड पैटर्न का उपयोग करते समय जिम्मेदारियों का मिश्रण नहीं होता है जो कि शायद ही परीक्षण योग्य है और डोमेन ऑब्जेक्ट में डेटा एक्सेस (क्वेरी) कोड को मिलाता है और ऐसा करने में चिंता का विषय है (जो वस्तु प्राप्त करता है) अपने आप??)। डेटा ट्रांसफर के लिए POCO बनाने के लिए हर कोई अभी भी स्वतंत्र है।

सब सब में, बहुत कोड का पुन: उपयोग और सरलता इस दृष्टिकोण के साथ प्रदान की जाती है कि मैं कुछ भी नहीं सोच सकता। कोई विचार?

और अपने महान पदों और निरंतर समर्पण के लिए आयेंडे को बहुत-बहुत धन्यवाद। यहाँ उसके विचार (क्वेरी ऑब्जेक्ट), मेरे नहीं।


1
दृढ़ता संस्थाएँ (आपके POCO) व्यवसाय / डोमेन संस्थाएँ नहीं हैं। और भंडार का उद्देश्य दृढ़ता से व्यवसाय (किसी भी) परत को अपघटित करना है।
माइकस् जूल 3'13

मैं कपलिंग को देखने में विफल हूं। POCO भाग पर कुछ सहमत हैं, लेकिन परवाह नहीं है। कुछ भी नहीं आप 'वास्तविक' POCO होने से रोकने के लिए और अभी भी इस दृष्टिकोण का उपयोग करें।
halex

1
संस्थाओं को सभी के लिए मूक पीओसी होना जरूरी नहीं है। वास्तव में, एंटिटीज में बिजनेस लॉजिक की डीडीडी भीड़ हर समय काम करती है। विकास की यह शैली एनएच या ईएफ के साथ बहुत अच्छी तरह से मिश्रण करती है।
क्रिस

1

मेरे लिए, यह एक सरल निर्णय है, अपेक्षाकृत कुछ कारकों के साथ। कारक हैं:

  1. डोमेन वर्ग के लिए भंडार हैं।
  2. मेरे कुछ एप्लिकेशन में, डोमेन कक्षाएं मेरी दृढ़ता (डीएएल) कक्षाओं के समान हैं, अन्य में वे नहीं हैं।
  3. जब वे समान होते हैं, तो ईएफ मुझे पहले से ही रिपॉजिटरी प्रदान कर रहा है।
  4. EF आलसी लोडिंग और IQueryable प्रदान करता है। मैं इन्हे पसन्द करता हूँ।
  5. EF पर रिपॉजिटरी / 'फेसिंग' / री-इम्प्लीमेंटेशन रिपॉजिटरी का मतलब आमतौर पर आलसी और IQueryable का नुकसान होता है

इसलिए, यदि मेरा ऐप # 2, अलग डोमेन और डेटा मॉडल को सही नहीं ठहरा सकता है, तो मैं आमतौर पर # 5 के साथ परेशान नहीं करूंगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.