MVVM WPF में ViewModel को एंटिटी फ्रेमवर्क डेटाबेस संदर्भ (मॉडल) को तार करने का सबसे अच्छा तरीका क्या है?


9

जैसा कि ऊपर प्रश्न में है: MVVM (WPF) में देखने के लिए इकाई फ्रेमवर्क डेटाबेस मॉडल (संदर्भ) को तार करने का सबसे अच्छा तरीका क्या है?

मैं WPF में MVVM पैटर्न सीख रहा हूं, उदाहरणों में से एक यह दिखाता है कि मॉडल को देखने के लिए मॉडल को कैसे लागू किया जाए, लेकिन उस उदाहरण में मॉडल सिर्फ साधारण वर्ग हैं, मैं MVVM को इकाई ढांचे के मॉडल (आधार प्रथम दृष्टिकोण) के साथ उपयोग करना चाहता हूं। देखने के लिए वायर मॉडल के लिए सबसे अच्छा तरीका है।

जवाब के लिए धन्यवाद।

//ctor of ViewModel 
public ViewModel()
{ 
db = new PackageShipmentDBEntities(); // Entity Framework generated class

ListaZBazy = new ObservableCollection<Pack>(db.Packs.Where(w => w.IsSent == false)); 
}

यह ViewModel का मेरा सामान्य ctor है, लगता है कि एक बेहतर तरीका है, मैं रिपॉजिटरी पैटर्न के बारे में पढ़ रहा था, निश्चित नहीं कि मैं इसे WPF MVVM के लिए अनुकूलित कर सकूं

जवाबों:


4

मैंने इस पर काफी गौर किया है और "पूर्ण" समाधान नहीं पाया है। रिपॉजिटरी पैटर्न एमवीसी अनुप्रयोगों के लिए आश्चर्यजनक रूप से काम करता है जहां संदर्भ कम रहता है क्योंकि यह एक अल्पकालिक नियंत्रक में मौजूद है, लेकिन समस्या तब होती है जब आप उसी संरचना को एक wpf ऐप पर लागू करने की कोशिश करते हैं जहां वीएम लंबे समय तक बना रह सकता है।

मैंने अतीत में इस समाधान का उपयोग किया है जो कि रेपो पैटर्न के कई हिस्सों की तुलना में बहुत अधिक सरल है, मैंने देखा है कि चीजों को एक अत्यधिक मात्रा में बाहर करने का प्रयास किया जाता है, जिसके परिणामस्वरूप कोड की अपठनीय मात्राएं पास होती हैं जो डिबग करना मुश्किल होता है। ये रहे कदम ...

  1. अपनी डेटा एक्सेस लेयर के रूप में कार्य करने के लिए EDMX के लिए एक अलग प्रोजेक्ट बनाएँ
  2. एक ही परियोजना के तहत एक "रिपॉजिटरी" फ़ोल्डर बनाएं
  3. "कार्य की इकाई" के रूप में कार्य करने के लिए एक बेस क्लास "BaseRepository" बनाएं। IDisposableआपको इसका उपयोग करने की अनुमति देगा using(){}और partialआपको अन्य रिपॉजिटरी को लागू करने की अनुमति देगा

    public partial class MyEntityRepository : IDisposable
    {
        MyEntities context = new MyEntities();
    
        public void Dispose()
        {
            context.Dispose();
        }
    }
    
  4. "MyOtherRepository" नामक एक अन्य फ़ाइल बनाएं। एक ही आंशिक वर्ग बनाएं, लेकिन उस फ़ाइल को शामिल करने के तरीके के आधार पर तरीकों को लागू करें

    public partial class MyEntityRepository
    {
        public void MyOtherMethodSave(EntityObject obj)
        {
            //work with context
            ...
    
            context.SaveChanges();
        }
    }
    

अब आपके वीएम में आप ऐसा कर सकते हैं ...

using(MyEntityRepository repo = new MyEntityRepository())
{
     repo.MyOtherMethodSave(objectToSave);
}

यह आपके सभी रिपॉजिटरी को एक वर्ग के तहत समूहित करता है ताकि आपको अलग-अलग संदर्भ से निपटना न पड़े। यह आपको तरीकों को अलग-अलग फाइलों में समूहित करके अलग-अलग रिपोज का प्रबंधन करने की अनुमति देता है और कोड दोहराव को रोकने में मदद करता है। उसके ऊपर, आपके संदर्भ उतने ही कम रहते हैं जितने कि वे इस पैटर्न का उपयोग किए बिना थे।

नुकसान यह है कि बड़े सिस्टम के साथ, आपके पास बहुत सारे तरीके हो सकते हैं जो आपके रेपो के तहत बंडल हो जाते हैं। उस मामले में एक समाधान कुछ बुनियादी सामान्य आदेशों जैसे "ढूंढना" या "जोड़ना" को लागू करना होगा, और अपने संबंधित भंडार में विशिष्ट लोगों को लागू करना होगा।


2
आप 'MyEntityRepository' EF के स्वयं के संदर्भ को प्रतिस्थापित कर सकते हैं और आपको वही परिणाम मिलेगा। जब तक आप ईपीएफ के संदर्भ को अपने स्वयं के "रिपॉजिटरी" के साथ लपेटना चाहते हैं, दोहराव बढ़ रहा है।
व्यंग्यात्मक

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

4

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

सीधे शब्दों में कहा, प्रत्येक ऑपरेशन के लिए, आप एक अलग ThisOperationCommandवर्ग बनाते हैं । इस वर्ग के अंदर आप सामान्य ईएफ संदर्भ के साथ काम करेंगे। तुम भी कुछ आधार वर्ग है EFCommandकि आप के लिए कुछ पाइपलाइन का उपयोग कर सकते हैं।

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

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


0

सरल परिदृश्यों के लिए मैंने निम्नलिखित का उपयोग किया है:

public class ViewModel : IDisposable {

    private EntitiesContext _context = new EntitiesContext();

    private SomeEntity _model;
    public SomeEntity Model {
       get { return _model; }
    }

    public View(int id) {
        _model = _context.SomeEntity.Find(id);
    }

    private ICommand _saveCommand = new RelayCommand(() => _context.SaveChanges());
    public ICommand SaveCommand {
        get { return _saveCommand; }
    }        

    public void Dispose() {
         _context.Dispose();
    }

}

1
इसके साथ समस्या यह है कि आपका संदर्भ अब संभावित रूप से "लंबे समय तक रहने वाला" है।
जूता

1
आपको कक्षा के अंदर संदर्भ का उदाहरण नहीं बनाना चाहिए, बल्कि उसे कंस्ट्रक्टर में इंजेक्ट करना चाहिए।
ऑस्कर मेडेरोस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.