2015-06-24 6 views
10

!!! कृपया this article पर रीडायरेक्ट न करें, क्योंकि यह नीचे वर्णित समस्या का समाधान नहीं करता है।LINQ2SQL: अज्ञात इकाइयों को लोड करते समय फ़ील्ड मानों को कैसे संशोधित करें?

मान लीजिए कि हम डेटाबेस में टेबल करते हैं:

SomeTable

  • आईडी (int)
  • डीटी (दिनांक)

हम एक Linq2Sql डेटा कॉन्फ़िगर किया है संदर्भ। और हमने कुछटेबल के लिए एक इकाई कॉन्फ़िगर की है: ऑनलोडेड विधि डीटी को इस तरह से संशोधित करती है कि डीटी की डेटटाइमकिंड यूटीसी बन जाती है (शुरुआत में यह निर्दिष्ट नहीं है)।

हम पूरी इकाई का उपयोग करके डेटा अनुरोध करते हैं, onLoaded विधि कहा जाता है::

अब यहाँ समस्या यह है

From x In ourDataContext.SomeTable Select x 

लेकिन हम तालिका का ही हिस्सा अनुरोध (और इसलिए एक गुमनाम उत्पन्न प्रकार), onLoaded नहीं बुलाया जाता है:

From x In ourDataContext.SomeTable Select x.DT 

यह स्पष्ट है कि onLoaded SomeTable इकाई में परिभाषित किया गया है, और अनाम प्रकार में नहीं।

फिलहाल मैं कस्टम संस्थाएं बनाने पर विचार करता हूं जो अनाम प्रकारों को प्रतिस्थापित करेंगे। लेकिन शायद किसी के पास बेहतर समाधान है?

from x in ourDataContext.SomeTable 
select DateTime.SpecifyKind(x.DT, DateTimeKind.Utc) 

आप इस अक्सर कर रही होगी, तो एक विस्तार विधि यह कम वर्बोज़ कर मदद कर सकता है:

उत्तर

1

हम समान समस्या थी के रूप में हम गुमनाम वस्तु के रूप में संस्था से क्षेत्रों का हिस्सा प्राप्त करने के लिए आवश्यक है और हमेशा पता है कि हम LINQ अनुरोध में अतिरिक्त कार्य का उपयोग किए बिना DateTimeKind.UTC के रूप में तिथि खाने की DateTimeKind है।

हमने बहुत सी चीजों की कोशिश की, लेकिन हमें केवल एक अच्छा पर्याप्त समाधान मिला - टी 4 के साथ लिंक 2 एसक्यूएल के लिए कोड जनरेशन।

पीएस यदि आप टी 4 के साथ लिंक 2 एसक्यूएल कोड पीढ़ी के बारे में अधिक जानना चाहते हैं, तो आप http://www.hanselman.com/blog/T4TextTemplateTransformationToolkitCodeGenerationBestKeptVisualStudioSecret.aspx

+0

मुझे लगता है कि अब के लिए एकमात्र तरीका है ...: / – Dima

0

आप क्वेरी भीतर DateTimeKind निर्दिष्ट कर सकते हैं तो फिर

public static class Ext 
{ 
    public static DateTime AsUtc(this DateTime dateTime) 
    { 
     return DateTime.SpecifyKind(dateTime, DateTimeKind.Utc); 
    } 

    public static DateTime? AsUtc(this DateTime? dateTime) 
    { 
     if(dateTime == null) return null; 
     return AsUtc(dateTime.Value); 
    } 
} 

अपने क्वेरी बन जाती है:

from x in ourDataContext.SomeTable select x.DT.AsUtc() 
+0

से शुरू कर सकते हैं यह कार्यक्षमता को Linq2Sql को प्रस्तुत करने का विचार तोड़ता है। अगर कुछ डेवलपर AsUtc का उपयोग करना भूल जाता है तो उसे गलत डेटा प्राप्त होगा। – Dima

3

लिंक 2 एसक्यूएल टेबल के लिए आंशिक कक्षाएं उत्पन्न करता है जिससे इसे विस्तार करना बहुत आसान हो जाता है। बस अपने समाधान (अपने स्वत: जनरेट db संदर्भ के रूप में ही नाम स्थान के अंदर) के लिए SomeTable.cs फ़ाइल जोड़ सकते हैं और किसी भी व्यवहार के साथ एक अतिरिक्त संपत्ति को परिभाषित आप की जरूरत:

public partial class SomeTable { 
    public System.DateTime CustomDT { 
     get { return DT.AddYears(120); } 
    } 
} 

अब आप यह सामान्य की तरह क्वेरी कर सकते हैं:

 var e = ctx.SomeTable.Select(x => new { x.CustomDT }).First(); 
     Console.WriteLine(e.CustomDT); 

अद्यतन:

टिप्पणियाँ मुझे लगता है कि समस्या आप देख रहे हैं जिम्मेदारियों का गलत जुदाई की वजह से है के आधार पर। आप अपने डीएएल को एक व्यावसायिक तर्क (डेटा परिवर्तन) जिम्मेदारी पारित करने की कोशिश कर रहे हैं।जबकि एल 2 एस यहां कुछ लचीलापन प्रदान करता है (ऊपर दिखाया गया है) यदि समाधान संतोषजनक नहीं है तो आपके पास अन्य विकल्प हैं:

  1. एल 2 एस डीएएल के ऊपर स्पष्ट परत। आम तौर पर यह एक रिपोजिटरी पैटर्न है जो एल 2 एस द्वारा स्वत: जेनरेट किए गए डीटीओ को बहुत समान करता है। इस मामले में आप उपभोक्ताओं को CustomDT का उपयोग करने के लिए मजबूर करने के लिए DT संपत्ति को छुपा सकते हैं।
  2. तर्क को डेटाबेस में रखें (विचार, गणना कॉलम, एसपी)। मैं किसी नए प्रोजेक्ट के लिए इस दृष्टिकोण पर विचार नहीं करता लेकिन यह कुछ विरासत अनुप्रयोगों के लिए व्यवहार्य विकल्प हो सकता है।
+0

इस विधि को स्वयं प्रश्न में वर्णित किया गया है, लेकिन मैं बेहतर दृष्टिकोण की तलाश में हूं। – Dima

+0

मैं नहीं देख सकता कि सवाल एक अतिरिक्त संपत्ति का उपयोग कैसे करता है जो आपके पास इस मुद्दे को संबोधित करता है। यह दोनों प्रक्षेपण (उदाहरण के रूप में) और चयन परिदृश्यों में काम करता है। – UserControl

+0

अच्छा, यह आसान है: हमें कस्टम कोड पेश करना होगा, जिसमें दो नुकसान हैं: 1. एक तृतीय-पक्ष डेवलपर अभी भी डीटी प्रॉपर्टी का उपयोग नहीं कर सकता है (इसलिए स्वचालित डीटी प्रॉपर्टी का पूरा विचार टूटा हुआ है) 2. कस्टम डीटी का उपयोग करते समय प्रश्नों में, LINQ2SQL अनुकूलन छोड़ देता है: यह केवल डीटी फ़ील्ड का अनुरोध करने के बजाय डेटाबेस से सभी तालिका फ़ील्ड का अनुरोध करता है। – Dima

0

आप क्वेरी हिस्से के लिए linq-to-sql का उपयोग करें और linq-to-objects का उपयोग DateTime संपत्ति आप चाहते हैं (आप वास्तव में एक गुमनाम प्रकार वापस नहीं कर रहे हैं) हड़पने के लिए कर सकता है।

(From x In ourDataContext.SomeTable _ 
Select x).AsEnumerable() _ 
      .Select(Function(x) x.DT) 
0

क्या आप इस कोड को आजमा सकते हैं? बेनामी प्रकार का उपयोग करने के बजाय, आप एक ही टेबल प्रकार निर्दिष्ट कर सकते हैं लेकिन केवल एक फ़ील्ड लोड कर सकते हैं। मुझे नहीं पता कि यह आपके मामले में काम करेगा या नहीं।

SomeTable.Select(x => new SomeTable { 
    DateField = x.DateField 
}) 

अन्यथा इसका कोई आसान समाधान नहीं है।

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