2010-09-08 13 views
6

मेरे पास एंटिटी फ्रेमवर्क 4, लैम्ब्डा एक्सप्रेशन और डेटा ट्रांसफर ऑब्जेक्ट्स (डीटीओ) के बारे में एक अर्द्ध जटिल सवाल है।ईएफ 4, लैम्ब्डा, रिपोजिटरी पैटर्न और डीटीओ

तो मेरे पास एक छोटी ईएफ 4 परियोजना है, और स्थापित ओओ सिद्धांतों के बाद, मेरे पास डेटा उपभोक्ताओं (जीयूआई) और डेटा मॉडल के बीच अमूर्तता की एक परत प्रदान करने के लिए एक डीटीओ है।

  • VideoDTO = डीटीओ getters/setters साथ, जीयूआई
  • VideoEntity = इकाई EF4
  • द्वारा उत्पन्न द्वारा प्रयोग किया जाता

मेरा प्रश्न जीयूआई द्वारा डीटीओ के उपयोग के चारों ओर घूमती है (और नहीं होने जीयूआई एंटिटी का बिल्कुल उपयोग करता है), डेटा लेयर में लैम्ब्डा पास करने की आवश्यकता के साथ संयुक्त। मेरी डेटा परत एड के साथ एक मूल भंडार पैटर्न है। बदलें, हटाएँ, जाओ, GetList, आदि तो जैसे एक हस्ताक्षर के साथ एक खोज विधि को लागू करने की कोशिश कर रहा:

public IEnumerable<VideoDTO> Find(Expression<Func<VideoEntity, bool>> exp) 
... 
_dataModel.Videos.Where(exp).ToList<Video>() 
--- 

मेरे समस्या/चिंता का विषय "exp" VideoDTO के बजाय प्रकार VideoEntity के होने की आवश्यकता होगी, है। मैं चिंताओं को अलग करना चाहता हूं ताकि जीयूआई इकाई वस्तुओं के बारे में नहीं जानता। लेकिन अगर मैं

Func<VideoDTO, bool> 

मैं तब LINQ नहीं कर सकता, जहां वास्तविक अभिव्यक्ति मॉडल का उपयोग करके उस अभिव्यक्ति पर।

वहाँ एक रास्ता एक Func<VideoEntity, bool>

करने के लिए एक Func<VideoDTO,bool> कन्वर्ट करने के लिए आदर्श रूप में मेरी विधि हस्ताक्षर Func<VideoDTO, bool> को स्वीकार करेंगे और इस तरह जीयूआई अंतर्निहित डेटा इकाई के लिए कोई संदर्भ होता है।

क्या यह पर्याप्त स्पष्ट है? आपकी मदद के लिए धन्यवाद


आप दोनों को प्रतिलिपि बनाने के लिए धन्यवाद।

मैं किसी ऑब्जेक्ट में खोज मानदंड को परिभाषित करने और LINQ अभिव्यक्ति में इसका उपयोग करने का विचार करूंगा। एक सीखने की परियोजना के रूप में इसका उपयोग करके, ईएफ 4 और एल 2 एस दोनों के साथ शुरू करें।

फिर से धन्यवाद!

उत्तर

0

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

आगे जाने के लिए आप एक इंटरफ़ेस (IVideoEntityQueryFields) के माध्यम से VideoEntity से खोजने योग्य फ़ील्ड का पर्दाफाश कर सकते हैं और अभिव्यक्ति में प्रकार के रूप में इसका उपयोग कर सकते हैं।

आप अपनी संस्थाओं के लिए एक इंटरफेस को जोड़ने के लिए नहीं करना चाहते हैं तो और अधिक जटिल विकल्प के लिए एक VideoEntityQuery वस्तु और कुछ है कि एक Expression<Func<VideoEntity,bool>> के लिए एक Expression<Func<VideoEntityQuery,bool>> तब्दील उपयोग करने के लिए है।

1

CQRS जैसे आर्किटेक्चर में इस तरह के रूपांतरण की आवश्यकता नहीं है & ऐप के लेखन पक्ष अलग-अलग हैं।

लेकिन आपके मामले में, आप अनुवाद से भाग नहीं सकते हैं।

सबसे पहले - आपको भंडार परिभाषित करते समय अधिक विशिष्ट होना चाहिए। रिपोजिटरी हस्ताक्षर चीज है आप जेनेरिक के बजाय स्पष्ट रखना चाहते हैं।

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

आपके उदाहरण में यह थोड़ा बेहतर कारण अभिव्यक्ति जेनेरिकता इकाई के बजाय डीटीओ से जुड़ा हुआ है।

:

यह मैं क्या (NHibernate.Linq का उपयोग कर, लेकिन यह विचार रहता है)

public class Application{ 
    public Project Project {get;set;}  
} 

public class ApplicationRepository{ 
public IEnumerable<Application> Search(SearchCriteria inp){ 
     var c=Session.Linq<Application>(); 
     var q=c.AsQueryable(); 
     if(!string.IsNullOrEmpty(inp.Acronym)) 
     q=q.Where(a=>a.Project.Acronym.Contains(inp.Acronym)); 
     /*~20 lines of similar code snipped*/ 
     return q.AsQueryable(); 
} 
} 

//used by client 
public class SearchCriteria{ 
public string Acronym{get;set;} 
/*some more fields that defines how we can search Applications*/ 
} 

आप अपने भाव रखने के लिए चाहते हैं, तो एक तरह से इस तरह मैन्युअल शब्दकोश परिभाषित करने के लिए होगा

var d=new Dictionary<Expression<Func<VideoDTO,object>>, 
        Expression<Func<VideoEntity,object>>{ 
    {x=>x.DtoPropNumberOne,x=>x.EntityPropNumberOne} /*, {2}, {3}, etc.*/ 
}; 

और बाद में उसका उपयोग:

//can You spot it? 
//client does not know explicitly what expressions dictionary contains 
_dataModel.Videos.Where(d[exp]).ToList<Video>(); 
//and I'm not 100% sure checking expression equality would actually work 

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

वैसे भी - जैसा कि मैंने कहा था, आपको इससे बचना चाहिए। अन्यथा - आप वास्तव में नाजुक कोड का उत्पादन करेंगे।

संबंधित मुद्दे