2009-03-27 13 views
5

यदि मेरे पास तीन इकाइयां, प्रोजेक्ट, प्रोजेक्ट रोल और व्यक्ति हैं, जहां कोई व्यक्ति विभिन्न परियोजनाओं का सदस्य हो सकता है और विभिन्न परियोजना भूमिकाओं (जैसे "प्रोजेक्ट लीड" या "प्रोजेक्ट सदस्य") में हो - तो आप इस तरह मॉडल कैसे करेंगे एक रिश्ता?डोमेन संचालित डिजाइन के साथ आप भूमिकाओं/रिश्तों को कैसे याद करते हैं?

डेटाबेस में, मैं वर्तमान में निम्नलिखित tablers है: परियोजना, व्यक्ति, पी के रूप में PersonId & ProjectId और एक FK रिश्ता के रूप में एक ProjectRoleId साथ ProjectRole Project_Person।

मैं वास्तव में यहां एक नुकसान में हूं क्योंकि मेरे द्वारा आने वाले सभी डोमेन मॉडल कुछ "डीडीडी" नियम तोड़ने लगते हैं। क्या इस समस्या के लिए कोई 'मानक' है?

मैंने एक सुव्यवस्थित ऑब्जेक्ट मॉडलिंग पर एक नज़र डाली थी और एक उदाहरण है कि एक परियोजना और प्रोजेक्ट मेम्बर कैसा दिखता है, लेकिन परियोजना में AddProjectMember() ProjectMember.AddProject() को कॉल करेगा। इसलिए परियोजना में परियोजना सदस्यों की एक सूची है, और प्रत्येक परियोजना मेम्बर में बदले में परियोजना का संदर्भ है। मुझे थोड़ा गड़बड़ लग रहा है।

अद्यतन

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

ProjectMembershipTypes को बनाया और संशोधित किया जा सकता है। ये "प्रोजेक्ट लीडर", "डेवलपर", "बाहरी सलाहकार" या कुछ अलग हो सकते हैं।

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

public class ProjectMember : IRole 
{ 
    public virtual int ProjectMemberId { get; set; } 
    public virtual ProjectMembershipType ProjectMembershipType { get; set; } 

    public virtual Person Person { get; set; } 
    public virtual Project Project { get; set; } 
    public virtual DateTime From { get; set; } 
    public virtual DateTime Thru { get; set; } 
    // etc... 
} 

प्रोजेक्टमेम्बरशिप टाइप: यानी। "परियोजना प्रबंधक", "डेवलपर", "सलाहकार"

public class ProjectMembershipType : IRoleType 
{ 
    public virtual int ProjectMembershipTypeId { get; set; } 
    public virtual string Name { get; set; } 
    public virtual string Description { get; set; } 

    // etc... 
} 

उत्तर

1

आप कई से अधिक रिश्तों को मॉडलिंग कर रहे हैं: एक परियोजना में बहुत से लोग काम कर सकते हैं, और एक व्यक्ति कई परियोजनाओं पर काम कर सकता है।

आप एक परियोजना भूमिका के रूप में संबंध मॉडल कर रहे हैं, जो व्यक्ति < -> परियोजना से द्वि-दिशात्मक लिंक के रूप में कार्य करने के अलावा, एक रोलटाइप भी रिकॉर्ड करता है और उस परियोजना पर उस रोलटाइप को भरने वाले व्यक्ति का प्रारंभ/अंत । (ध्यान दें कि अंग्रेजी कैसे काम करता है "वह" डाटाबेस एफके या कोड में, पॉइंटर/संदर्भ के लिए खड़ा है?)

उन एफके के कारण, हम डेटाबेस में परियोजना भूमिका के माध्यम से व्यक्ति से ग्राफ का अनुसरण कर सकते हैं, परियोजना के लिए:

select a.person_id, b.project_role_id, c.project_id 
from person a join project_role b on (a.id = b.person_id) 
join project c on (b.project_id = c.id) 
where a.person_id = ? 

या क्या हम दूसरी दिशा में इसे का पालन कर सकते हैं, परियोजना से:

select a.person_id, b.project_role_id, c.project_id 
from person a join project_role b on (a.id = b.person_id) 
join project c on (b.project_id = c.id) 
where c.project_id = ? 

आदर्श रूप में, हम सी # कोड में भी ऐसा ही करने में सक्षम होना चाहते हैं। तो हाँ, हम चाहते हैं कि एक व्यक्ति की एक सूची हो, और एक सूची रखने के लिए परियोजना, और एक व्यक्ति और एक परियोजना के लिए एक परियोजना रोल संदर्भ।

हाँ, Project::addPerson(Person&) वास्तव में, Project::addProjectRole(ProjectRole&) होना चाहिए जब तक कि हम तय करते हैं कि Project::addPerson(Person&) प्रपत्र की एक सुविधा विधि है:

void Project::addPerson(Person& p) { 
    this.addProjectRole(new ProjectRole(p, &this, RoleType::UNASSIGNED) ; 
} 

एक ProjectRole एक सूची नहीं है, यह है-एक एक व्यक्ति के संदर्भ में और एक परियोजना का संदर्भ। इसमें मूल्य, प्रारंभ तिथि, समाप्ति तिथि और एक रोलटाइप (जो या तो एक enum है, या एक वर्ग उदाहरण है जो एक enum मान की नकल करता है - यानी, प्रति enum प्रकार केवल एक वस्तु है, और यह है स्टेटलेस, अपरिवर्तनीय और बेवकूफ, और इस तरह कई प्रोजेक्ट रोल के बीच तेज)।

अब इसका मतलब यह नहीं होना चाहिए कि डेटाबेस से एक व्यक्ति को पुन: प्राप्त का कारण होना चाहिए पूरे डेटाबेस कोड में वस्तु ग्राफ में reified किया जाता है; आलसी प्रॉक्सी जो केवल उपयोग पर पुनर्प्राप्त होती हैं, हमें इससे बचा सकती हैं। फिर यदि हम वर्तमान में व्यक्ति से संबंधित हैं, न कि उनकी भूमिकाएं (और प्रोजेक्ट्स, हम केवल व्यक्ति को पुनः प्राप्त कर सकते हैं। (उदाहरण के लिए, एनएचबीर्नेट, मुझे लगता है कि यह कम या कम निर्बाध रूप से करता है।)

मूल रूप से , मुझे लगता है कि:

1) यह कई से अधिक संबंधों का प्रतिनिधित्व करने का एक मानक तरीका है; 2) यह अतिरिक्त डेटा (जब, किस तरह का) और उसके संबंध के संबंध में मानक है; 3) आपको काफी सही विचार मिल गया है, और यहां प्रतिक्रिया प्राप्त करने में सही मायने में ईमानदार हैं।

0

आप भूमिका एक व्यक्ति एक परियोजना में है के साथ भ्रमित नहीं एक भूमिका का "विवरण" कर रहे हैं? "रोलडिस्क्रिप्शन" अवधारणा (एक 'रोल-क्लास' बोलने के लिए) जोड़ना, और परियोजनाओं में वास्तविक व्यक्तियों का जिक्र करने वाली "रोलइंस्टेंस" ऑब्जेक्ट्स मदद कर सकती हैं।

+0

मुझे कोई जानकारी नहीं है, यह संभव है, मुझे यकीन नहीं है कि आपका मतलब क्या है – kitsune

+0

मुझे डर है कि मैं संबंधपरक डेटाबेस युग से तारीख हूं लेकिन बहुत अधिक ओओडी खाया ... मैं 'दूसरा समाधान' का जिक्र कर रहा हूं जेमी का जवाब – xtofl

0

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

public class ProjectPerson : Person 
{ 
    public string Role { get; set; } 
} 

आपका परियोजना वर्ग अब ProjectPerson का एक संग्रह है, लेकिन व्यक्ति वर्ग परियोजना का एक संग्रह है क्योंकि यह करने के लिए कोई मतलब नहीं है है भूमिका जोड़ने के लिए परियोजना वर्ग का विस्तार करें। व्यक्ति के परिप्रेक्ष्य से किसी परियोजना पर भूमिका निभाने के लिए आपको कुछ अतिरिक्त काम करना होगा (ProjectPerson संग्रह में व्यक्ति को देखें)।

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

यह विचार करना महत्वपूर्ण है कि आपकी डेटा एक्सेस रणनीति समाधान का चयन करने में मॉडल का कितनी अच्छी तरह से समर्थन करेगी। आप उन परिदृश्यों से बचना चाहते हैं जहां संग्रहण लोड करना संग्रह में प्रत्येक ऑब्जेक्ट के लिए डेटाबेस में एक या अधिक यात्रा की आवश्यकता होती है।

+0

मैं 'प्रोजेक्टर्सन' वर्ग के खिलाफ सलाह दूंगा, क्योंकि जल्द से जल्द या बाद में आप 'बिलबलपर्सन', 'इंटर्नशिपपर्सन' और 'टेरफेयरपर्सन' के साथ समाप्त हो जाएंगे, जो सभी एक ही 'असली' व्यक्ति का जिक्र करते हैं। मैं विरासत समाधान के बजाय संबंधों के साथ रहना होगा। – xtofl

+0

मुझे आपकी तर्क समझ में नहीं आ रहा है: प्रस्तावित समाधान ड्राइव व्यक्ति के अतिरिक्त एक्सटेंशन कैसे बनायेगा? प्रोजेक्ट के संदर्भ में एक प्रोजेक्टर्सन भूमिका में एक व्यक्ति है। डेटाबेस शर्तों में व्यक्ति तालिका में कई से अधिक लिंक तालिका में शामिल होने से इसे पुनर्प्राप्त किया जाता है। –

3

यहाँ कैसे मैं इसे संभाल होता है:

class Person 
{ 
    string Name { get; set; } 
    IList<Role> Roles { get; private set; } 
} 

class Role 
{ 
    string Name { get; set; } 
    string Description { get; set; } 
    IList<Person> Members { get; private set; } 
} 

class Project 
{ 
    string Name { get; set; } 
    string Description { get; set; } 
    IList<ProjectMember> Members { get; private set; } 
} 

class ProjectMember 
{ 
    Project Project { get; private set; } 
    Person Person { get; set; } 
    Role Role { get; set; } 
} 

ProjectMember वर्ग उन सब को एक साथ लाता है। यह मॉडल आपको अलग-अलग भूमिकाओं के साथ अलग-अलग परियोजनाओं में एक ही व्यक्ति को असाइन करने की लचीलापन देता है (उदाहरण के लिए वह प्रोजेक्टए पर डेवलपर हो सकता है, और प्रोजेक्टबी पर एक परीक्षक)।

कृपया भूमिका विशिष्ट कक्षाएं न बनाएं - वह सबक पहले से ही सीखा है।

  1. रन "बिन \ डिबग \ RolesRelationshipsSample.exe"
  2. पुस्तकालय प्रतीक को डबल क्लिक करें संस्थाओं बनाने के लिए:

    मैं एक sample app प्रदर्शित करने के लिए यह (यह भी रिश्ते भी शामिल है) बना लिया है

  3. खींचें/उन्हें उचित रिश्तों

कोड के साथ खेलने के लिए स्वतंत्र महसूस आवंटित करने के लिए छोड़ देते हैं। उम्मीद है यह आपको उपयोगी होगा।

+0

धन्यवाद! मैं आपके जैसे ही दिशा में गया, कृपया मेरा अद्यतन प्रश्न देखें। – kitsune

+0

@ विजय पटेल भूमिका विशिष्ट वर्ग क्यों नहीं बनाते? क्या होगा यदि प्रत्येक भूमिका परियोजना में विभिन्न कार्रवाइयां कर सकती है? – richard

+0

@ रिचर्ड: मेरे उदाहरण से, "भूमिका" से उप-वर्गीकरण कोई मुद्दा नहीं है। मुझे लगता है कि मैं नीचे जेमी विचार से परिदृश्य के लिए और अधिक बता रहा था http://stackoverflow.com/a/689618/80369 –

0

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

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

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