एक ही इकाई को विभिन्न तालिकाओं में मैप करना


9

थोड़ा सा डोमेन ज्ञान

मैं एक पीओएस (प्वाइंट ऑफ सेल्स) सॉफ्टवेयर लिख रहा हूं जो सामान का भुगतान करने या उन्हें वापस करने की अनुमति देता है। भुगतान या रिफंड करते समय, किसी को निर्दिष्ट करने की आवश्यकता है कि धन हस्तांतरण का उपयोग करने के लिए क्या अर्थ है: नकद, ईएफटी (~ = क्रेडिट कार्ड), वफादारी कार्ड, वाउचर, आदि।

इन मनी ट्रांसफर का मतलब है एक सीमित और मूल्यों का ज्ञात सेट (एक प्रकार का ईनाम)।

मुश्किल हिस्सा यह है कि मुझे पीओएस टर्मिनल पर भुगतान और धनवापसी (दोनों सेट अलग-अलग हो सकते हैं) के लिए इन साधनों का एक कस्टम सबसेट स्टोर करने में सक्षम होना चाहिए।

उदाहरण के लिए:

  • उपलब्ध भुगतान का अर्थ है: नकद, ईएफ़टी, लॉयल्टी कार्ड, वाउचर
  • उपलब्ध धनवापसी का अर्थ है: नकद, वाउचर

कार्यान्वयन की वर्तमान स्थिति

मैं निम्नलिखित के रूप में धन हस्तांतरण की अवधारणा को लागू करने का चयन करता हूं:

public abstract class MoneyTransferMean : AggregateRoot
{
    public static readonly MoneyTransferMean Cash = new CashMoneyTransferMean();
    public static readonly MoneyTransferMean EFT = new EFTMoneyTransferMean();
    // and so on...

    //abstract method

    public class CashMoneyTransferMean : MoneyTransferMean
    {
        //impl of abstract method
    }

    public class EFTMoneyTransferMean : MoneyTransferMean
    {
        //impl of abstract method
    }

    //and so on...
}

इसका कारण यह नहीं है कि "सादा दुश्मनी" यह है कि इन वर्गों के अंदर कुछ व्यवहार मौजूद है। मुझे फ्लुएंनहाइबरनेट मैपिंग (नीचे देखें) में उन्हें संदर्भित करने के लिए आंतरिक (सार्वजनिक के बजाय) निजी कक्षाओं की घोषणा करनी पड़ी।

इसका उपयोग कैसे किया जाता है

भुगतान और धनवापसी दोनों साधन हमेशा एक सेट के रूप में डीबी से / में संग्रहीत या पुनर्प्राप्त किए जाते हैं। वे वास्तव में दो अलग-अलग सेट हैं भले ही दोनों सेटों के अंदर कुछ मूल्य समान हों।

केस 1 का उपयोग करें: भुगतान / धनवापसी के नए सेट को परिभाषित करें

  • सभी मौजूदा भुगतान / धनवापसी साधनों को हटा दें
  • नया डालें

केस 2 का उपयोग करें: सभी भुगतान / धनवापसी साधनों को पुनः प्राप्त करें

  • सभी संग्रहीत भुगतान / धनवापसी साधनों का एक संग्रह प्राप्त करें

मुसीबत

मैं हठ पहलू पर अपने मौजूदा डिजाइन के साथ फंस गया हूं। मैं NHibernate (FluentNHibernate के साथ वर्ग मानचित्र घोषित करने के लिए) का उपयोग कर रहा हूं और मुझे इसे कुछ मान्य DB स्कीमा में मैप करने का तरीका नहीं मिल रहा है।

मैंने पाया कि इकाई-नाम का उपयोग करके कई बार कक्षा को मैप करना संभव है लेकिन मुझे यकीन नहीं है कि यह उपवर्गों के साथ संभव है।

मैं जो करने के लिए तैयार नहीं हूं, वह है MoneyTransferMean सार्वजनिक एपीआई को बदलने के लिए इसे जारी रखने में सक्षम होना (उदाहरण के bool isRefundलिए दोनों के बीच अंतर करना)। हालाँकि कुछ निजी विवेचक क्षेत्र को जोड़ना या ठीक है।

मेरी वर्तमान मानचित्रण:

public sealed class MoneyTransferMeanMap : ClassMap<MoneyTransferMean>
{
    public MoneyTransferMeanMap()
    {
        Id(Entity.Expressions<MoneyTransferMean>.Id);
        DiscriminateSubClassesOnColumn("Type")
            .Not.Nullable();
    }
}

public sealed class CashMoneyTransferMeanMap : SubclassMap<MoneyTransferMean.CashMoneyTransferMean>
{
    public CashMoneyTransferMeanMap()
    {
        DiscriminatorValue("Cash");
    }
}

public sealed class EFTMoneyTransferMeanMap : SubclassMap<MoneyTransferMean.EFTMoneyTransferMean>
{
    public EFTMoneyTransferMeanMap()
    {
        DiscriminatorValue("EFT");
    }
}

//and so on...

हालाँकि यह मानचित्रण केवल 1 तालिका का निर्माण करता है और इस तालिका को क्वेरी करते समय मैं भुगतान / धनवापसी में अंतर नहीं कर सकता।

मैंने MoneyTransferMeanअलग-अलग तालिका और इकाई-नाम दोनों का उल्लेख करते हुए दो मैपिंग घोषित करने की कोशिश की, लेकिन यह मुझे एक अपवाद की ओर ले जाता है Duplicate class/entity mapping MoneyTransferMean+CashMoneyTransferMean

मैंने उपवर्ग मैपिंग की नकल करने की भी कोशिश की, लेकिन मैं "पैरेंट मैपिंग" निर्दिष्ट करने में असमर्थ हूं, जो मुझे ऊपर के समान अपवाद की ओर ले जाता है।

सवाल

क्या मेरी मौजूदा डोमेन संस्थाओं को बनाए रखने के लिए कोई समाधान मौजूद है?

यदि नहीं, तो मुझे अपनी संस्थाओं पर NHibnernate के साथ लगातार बने रहने के लिए सबसे छोटा रिफ्लेक्टर क्या होगा?


1
What I'm not ready to do is to alter the MoneyTransferMean public API to be able to persist it (for example adding a bool isRefund to differentiate between the two).: क्यों नहीं? यह सरल और मीठा बदलाव है जो आपकी समस्या को हल करना चाहिए। आप तीन संभावित मूल्यों के साथ कर सकते हैं (हालांकि दो भी डुप्लिकेट रिकॉर्ड या के साथ क्या होगा Flagप्रकार): Payment, Refund, Both। यदि आपके लिए दो मूल्य हैं, तो boolसंपत्ति महान है।
अमित जोशी

1
आप डेटाबेस में उन भुगतान विधियों को क्यों संग्रहीत करना चाहते हैं? नाम के अलावा वहां क्या स्थिति है?
बरहलक

@AmitJoshi जबकि इस तरह के एक छोटे से बदलाव से समस्या (सतह पर) हल हो सकती है, मैं तर्क को जोड़ने से बचना चाहता हूं जो मेरे डोमेन में व्यवसाय से संबंधित नहीं है।
चित्तीदार

@berhalak वास्तव में, डेटाबेस में इन्हें संग्रहीत करना थोड़ा क्लिंकी लगता है। हालाँकि यह प्रोजेक्ट की एक आवश्यकता है जो सभी राज्य डेटाबेस में होना चाहिए।
चित्तीदार

जवाबों:


0

आप सभी सामान्य गुणों (फ़ील्ड) के साथ एक एकल इकाई MoneyTransferMean क्यों नहीं बनाते हैं , यह निर्धारित करने के लिए केवल 2 अतिरिक्त फ़ील्ड्स (बूलियन) जोड़ें कि क्या MoneyTransferMean या तो भुगतान या धनवापसी है, या दोनों ???? इसे जारी रखें या नहीं।

इसके अलावा यह आईडी (पीके) के साथ एक अतिरिक्त इकाई के साथ किया जा सकता है, एक ही अतिरिक्त क्षेत्र जोड़ सकते हैं, रिश्ता 1: 1 मनीट्रांसफ्रेम के साथ होगा। बदसूरत, मुझे पता है, लेकिन यह काम करना चाहिए।


मैं ऐसी जटिलता नहीं जोड़ना चाहता जो मेरे डोमेन प्रोजेक्ट से संबंधित डोमेन न हो (जैसे कि बूलियन जोड़ना, जिस पर बाद में / और ज़रूरत पड़ती है)। इसके अलावा, मैं नहीं चाहता कि जो लोग इन वर्गों का उपयोग गलती करने के लिए करेंगे (बूलियन की जांच करने के लिए भूलकर और यह सोचकर कि प्रत्येक मूल्य उदाहरण के लिए धनवापसी का मतलब है)। यह सब गवाह है।
चित्तीदार

0

मैं दूसरा और जो @ DEVX75 सुझाता हूं, उसमें आपके लेन-देन के प्रकार अनिवार्य रूप से एक ही अवधारणा का वर्णन कर रहे हैं, हालांकि एक + ve है जबकि दूसरा है -ve। मैं शायद सिर्फ एक बूलियन फ़ील्ड जोड़ूंगा, और भुगतान से धन वापसी के लिए अलग रिकॉर्ड होगा।

मान लें कि आपके पास एक UID है और ID के रूप में लेबल नाम का उपयोग नहीं कर रहे हैं, तो आप साधनों के लिए डुप्लिकेट नामों की अनुमति दे सकते हैं, और उदाहरण के लिए दो नकद प्रविष्टियाँ शामिल कर सकते हैं:

यूआईडी, लेबल, इस्रफंड

1, नकद, झूठा

2, नकद, सच

3, वाउचर, गलत

4, वाउचर, सच

तो आप आसानी से निम्नलिखित प्राप्त कर सकते हैं:

लेन-देन का प्रकार = मनीट्रांसफ़ेरमन.सर्फ़ंड? "रिफंड": "भुगतान"

लेनदेन मूल्य = MoneyTransferMean.IsRefund? MoneyTransfer.amount * -1: MoneyTransfer.amount

इस तरह, यदि आपके लेनदेन में आपने MoneyTransferMean.UID = 2 का संदर्भ दिया है, तो आप जानते हैं कि यह एक नकद वापसी है, बजाय यह जानने के कि यह एक लेनदेन प्रकार है जो या तो नकद वापसी या नकद भुगतान हो सकता है।


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

0

अंत में, मैं अपने इकाई को दोहराने के समस्या का समाधान करने का निर्णय लिया MoneyTransferMeanदो संस्थाओं में PaymentMeanऔर RefundMean

हालांकि कार्यान्वयन के समान, दो संस्थाओं के बीच का अंतर व्यवसाय में समझ में आता है और मेरे लिए सबसे कम समाधान था।

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